home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / DIAGTOOL / MEMSZ240.ZIP;1 / MEMSIZE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-23  |  123.8 KB  |  3,205 lines

  1. /**************************************************************** MEMSIZE.CPP
  2.  *                                                                          *
  3.  * System Resources Monitor                                                 *
  4.  *                                                                          *
  5.  * (C) Copyright 1991-1994 by Richard W. Papo.                              *
  6.  *                                                                          *
  7.  * This is 'FreeWare'.  As such, it may be copied and distributed           *
  8.  * freely.  If you want to use part of it in your own program, please       *
  9.  * give credit where credit is due.  If you want to change the              *
  10.  * program, please refer the change request to me or send me the            *
  11.  * modified source code.  I can be reached at CompuServe 72607,3111         *
  12.  * and on Internet at RPapo@Msen.com.                                       *
  13.  *                                                                          *
  14.  ****************************************************************************/
  15.  
  16. // Bugs to Fix:
  17. //
  18. //   (1) When Float To Top is active, then the E editor dies upon displaying
  19. //       its file-type-set dialog.  CLOCK has the same problem.  IBM is helping.
  20. //
  21. // Things to do:
  22. //
  23. //   (1) Provide an item to serve as a button to cause a secondary
  24. //       drive status window to be displayed (requested by Leland Sheppard).
  25. //
  26. //   (2) Provide colored highlights for different levels, configurable
  27. //       by item.
  28. //
  29.  
  30. #define INCL_BASE
  31. #define INCL_PM
  32. #include <os2.h>
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37.  
  38. #include "debug.h"
  39. #include "helpwin.h"
  40. #include "module.h"
  41. #include "process.h"
  42. #include "profile.h"
  43. #include "restring.h"
  44. #include "support.h"
  45. #include "window.h"
  46.  
  47. #include "about.h"
  48. #include "config.h"
  49.  
  50. #include "items.h"
  51.  
  52. #include "memsize.h"
  53.  
  54. #define STATIC
  55.  
  56.  
  57. /****************************************************************************
  58.  *                                                                          *
  59.  *                       Definitions & Declarations                         *
  60.  *                                                                          *
  61.  ****************************************************************************/
  62.  
  63.   // Constants
  64.  
  65. #define WM_REFRESH        (WM_USER)
  66.  
  67. #define MAX_DRIVES        (26)
  68. #define DRIVE_ERROR       (0xFFFFFFFFL)
  69.  
  70. enum
  71. {
  72.   ITEM_CLOCK,
  73.   ITEM_ELAPSEDTIME,
  74.   ITEM_MEMORYFREE,
  75.   ITEM_VIRTUALFREE,
  76.   ITEM_SWAPFILESIZE,
  77.   ITEM_SWAPDISKFREE,
  78.   ITEM_SPOOLFILESIZE,
  79.   ITEM_CPULOAD,
  80.   ITEM_TASKCOUNT,
  81.   ITEM_TOTALFREE,
  82.   ITEM_BASE_COUNT
  83. } ;
  84.  
  85.  
  86.   // Data Types
  87.  
  88. typedef struct {
  89.   BOOL Active ;
  90.   PULONG Counter ;
  91.   PUSHORT Interval ;
  92.   PBYTE Priority ;
  93.   HWND Owner ;
  94. } MONITOR_PARMS, *PMONITOR_PARMS ;
  95.  
  96. typedef struct {
  97.   BOOL Active ;
  98.   ULONG Counter ;
  99. } COUNTER_PARMS, *PCOUNTER_PARMS ;
  100.  
  101. typedef struct {      // Parameters saved to system.
  102.  
  103.   // The Display Item List - - -
  104.   Item           *Items [ ITEM_BASE_COUNT + MAX_DRIVES ] ;
  105.   int             ItemCount ;
  106.  
  107.   // Data required for the display item objects to function.
  108.   ULONG           IdleCount ;
  109.   ULONG           MaxCount ;
  110.   BYTE            SwapPath [_MAX_PATH] ;
  111.   ULONG           MinFree ;
  112.   PBYTE           SpoolPath ;
  113.   COUNTRYINFO     CountryInfo ;
  114.   char            szAm [3] ;
  115.   char            szPm [3] ;
  116.   ResourceString *Day ;
  117.   ResourceString *Days ;
  118.   ResourceString *DaysOfWeek ;
  119.   ResourceString *DriveError ;
  120.  
  121.   // Window size and location
  122.   SWP    Position ;
  123.   BOOL   fPosition ;
  124.  
  125.   // User Options
  126.   BOOL   HideControls ;
  127.   BOOL   fHideControls ;
  128.  
  129.   BOOL   Float ;
  130.   BOOL   fFloat ;
  131.  
  132.   BOOL   Animate ;
  133.   BOOL   fAnimate ;
  134.  
  135.   BOOL   ShowFileSystemNames ;
  136.   BOOL   fShowFileSystemNames ;
  137.  
  138.   BOOL   ShowDiskLabels ;
  139.   BOOL   fShowDiskLabels ;
  140.  
  141.   BYTE   MonitorPriority ;
  142.   BOOL   fMonitorPriority ;
  143.  
  144.   USHORT TimerInterval ;
  145.   BOOL   fTimerInterval ;
  146.  
  147.   // Presentation Parameters
  148.   BYTE   FontNameSize [80] ;
  149.   BOOL   fFontNameSize ;
  150.  
  151.   COLOR  BackColor ;
  152.   BOOL   fBackColor ;
  153.  
  154.   COLOR  TextColor ;
  155.   BOOL   fTextColor ;
  156.  
  157. } INIDATA, *PINIDATA ;
  158.  
  159. typedef struct {      // Data structure for window.
  160.    Process       *Proc ;
  161.    Module        *Library ;
  162.    Profile       *IniFile ;
  163.  
  164.    INIDATA        IniData ;
  165.  
  166.    TID            IdleLoopTID ;
  167.    COUNTER_PARMS  IdleLoopParms ;
  168.  
  169.    TID            MonitorTID ;
  170.    MONITOR_PARMS  MonitorParms ;
  171.  
  172.    HWND           hwndTitleBar ;
  173.    HWND           hwndSysMenu ;
  174.    HWND           hwndMinMax ;
  175.  
  176.    ULONG          Drives ;
  177.  
  178.    long           Width ;
  179.    long           Height ;
  180. } DATA, *PDATA ;
  181.  
  182. typedef struct {
  183.    short Filler ;
  184.    Process *Proc ;
  185.    Module *Library ;
  186.    Profile *IniFile ;
  187. } PARMS, *PPARMS ;
  188.  
  189.  
  190.   // Function Prototypes
  191.  
  192. extern int main ( int argc, char *argv[] ) ;
  193.  
  194. STATIC FNWP MessageProcessor ;
  195.  
  196. STATIC METHODFUNCTION Create ;
  197. STATIC METHODFUNCTION Destroy ;
  198. STATIC METHODFUNCTION Size ;
  199. STATIC METHODFUNCTION SaveApplication ;
  200. STATIC METHODFUNCTION Paint ;
  201. STATIC METHODFUNCTION Command ;
  202. STATIC METHODFUNCTION ResetDefaults ;
  203. STATIC METHODFUNCTION HideControlsCmd ;
  204. STATIC METHODFUNCTION Configure ;
  205. STATIC METHODFUNCTION About ;
  206. STATIC METHODFUNCTION ButtonDown ;
  207. STATIC METHODFUNCTION ButtonDblClick ;
  208. STATIC METHODFUNCTION PresParamChanged ;
  209. STATIC METHODFUNCTION SysColorChange ;
  210. STATIC METHODFUNCTION QueryKeysHelp ;
  211. STATIC METHODFUNCTION HelpError ;
  212. STATIC METHODFUNCTION ExtHelpUndefined ;
  213. STATIC METHODFUNCTION HelpSubitemNotFound ;
  214. STATIC METHODFUNCTION Refresh ;
  215.  
  216. STATIC int GetIniData ( HAB Anchor, HMODULE Library, HINI IniHandle, PINIDATA IniData ) ;
  217. STATIC VOID PutIniData ( HINI IniHandle, PINIDATA IniData ) ;
  218.  
  219. STATIC PSZ ScanSystemConfig ( HAB Anchor, PSZ Keyword ) ;
  220.  
  221. STATIC void ResizeWindow ( HWND hwnd, PINIDATA IniData ) ;
  222.  
  223. STATIC void HideControls
  224. (
  225.   BOOL fHide,
  226.   HWND hwndFrame,
  227.   HWND hwndSysMenu,
  228.   HWND hwndTitleBar,
  229.   HWND hwndMinMax
  230. ) ;
  231.  
  232. STATIC void UpdateWindow ( HWND hwnd, PDATA Data, BOOL All ) ;
  233.  
  234. STATIC VOID _Optlink MonitorLoopThread ( PVOID Parameter ) ;
  235.  
  236. STATIC VOID UpdateDriveList
  237. (
  238.   HAB Anchor,
  239.   HMODULE Library,
  240.   HINI IniHandle,
  241.   PINIDATA IniData,
  242.   ULONG OldDrives,
  243.   ULONG NewDrives
  244. ) ;
  245.  
  246. STATIC int CheckDrive ( USHORT Drive, PBYTE FileSystem, PBYTE DiskLabel ) ;
  247.  
  248. STATIC ULONG CalibrateLoadMeter ( PCOUNTER_PARMS Parms ) ;
  249.  
  250. STATIC VOID _Optlink CounterThread ( PVOID Parameter ) ;
  251.  
  252.  
  253.   // Global Data
  254.  
  255. HMODULE LibraryHandle ;
  256.  
  257.  
  258. /****************************************************************************
  259.  *                                                                          *
  260.  *      Program Mainline                                                    *
  261.  *                                                                          *
  262.  ****************************************************************************/
  263.  
  264. extern int main ( int argc, char *argv[] ) {
  265.  
  266.  /***************************************************************************
  267.   * Initialize the process.                                                 *
  268.   ***************************************************************************/
  269.  
  270.   Process Proc ;
  271.  
  272.  /***************************************************************************
  273.   * Open the resource library.                                              *
  274.   ***************************************************************************/
  275.  
  276.   Module Library ( PSZ(PROGRAM_NAME) ) ;
  277.   LibraryHandle = Library.QueryHandle() ;
  278.  
  279.  /***************************************************************************
  280.   * Get the program title.                                                  *
  281.   ***************************************************************************/
  282.  
  283.   ResourceString Title ( Library.QueryHandle(), IDS_TITLE ) ;
  284.  
  285.  /***************************************************************************
  286.   * Decipher command-line parameters.                                       *
  287.   ***************************************************************************/
  288.  
  289.   BOOL Reset = FALSE ;
  290.  
  291.   ResourceString ResetCommand ( Library.QueryHandle(), IDS_PARMS_RESET ) ;
  292.  
  293.   while ( --argc ) {
  294.  
  295.     argv ++ ;
  296.  
  297.     if ( *argv[0] == '?' ) {
  298.       ResourceString Message ( Library.QueryHandle(), IDS_PARAMETERLIST ) ;
  299.       WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
  300.         PSZ(Title), 0, MB_ENTER | MB_NOICON ) ;
  301.       return ( 0 ) ;
  302.     }
  303.  
  304.     if ( !stricmp ( *argv, PCHAR(ResetCommand) ) ) {
  305.       Reset = TRUE ;
  306.       continue ;
  307.     }
  308.  
  309.     {
  310.       ResourceString Format ( Library.QueryHandle(), IDS_ERROR_INVALIDPARM ) ;
  311.       BYTE Message [200] ;
  312.       sprintf ( PCHAR(Message), PCHAR(Format), *argv ) ;
  313.       WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, Message,
  314.         PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  315.       abort ( ) ;
  316.     }
  317.   }
  318.  
  319.  /***************************************************************************
  320.   * Create the help instance.                                               *
  321.   ***************************************************************************/
  322.  
  323.   ResourceString HelpTitle ( Library.QueryHandle(), IDS_HELPTITLE ) ;
  324.  
  325.   HelpWindow Help ( Proc.QueryAnchor(), 0,
  326.     ID_MAIN, PSZ(PROGRAM_NAME ".hlp"), PSZ(HelpTitle) ) ;
  327.  
  328.   if ( Help.QueryHandle() == 0 ) {
  329.     ERRORID Error = WinGetLastError ( Proc.QueryAnchor() ) ;
  330.     ResourceString Format ( Library.QueryHandle(), IDS_ERROR_CREATEHELP ) ;
  331.     CHAR Message [200] ;
  332.     sprintf ( Message, PCHAR(Format), Error ) ;
  333.     Log ( "%s", Message ) ;
  334.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
  335.       PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  336.   }
  337.  
  338.  /***************************************************************************
  339.   * Open/create the profile file.  Reset if requested.                      *
  340.   ***************************************************************************/
  341.  
  342.   Profile IniFile ( PSZ(PROGRAM_NAME),
  343.     Proc.QueryAnchor(), Library.QueryHandle(),
  344.     IDD_PROFILE_PATH, Help.QueryHandle(), Reset ) ;
  345.  
  346.   if ( IniFile.QueryHandle() == 0 ) {
  347.     ResourceString Message ( Library.QueryHandle(), IDS_ERROR_PRFOPENPROFILE ) ;
  348.     Log ( "%s", PSZ(Message) ) ;
  349.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
  350.       PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  351.     abort ( ) ;
  352.   }
  353.  
  354.  /***************************************************************************
  355.   * Read the profile to find out if we're to animate the frame window.      *
  356.   ***************************************************************************/
  357.  
  358.   BOOL Animate = FALSE ;
  359.   ULONG Size ;
  360.   if
  361.   (
  362.     PrfQueryProfileSize ( IniFile.QueryHandle(), PSZ(PROGRAM_NAME), PSZ("Animate"), &Size )
  363.     AND
  364.     ( ( Size == sizeof(Animate) ) OR ( Size == sizeof(short) ) )
  365.     AND
  366.     PrfQueryProfileData ( IniFile.QueryHandle(), PSZ(PROGRAM_NAME), PSZ("Animate"), &Animate, &Size )
  367.   )
  368.   {
  369.     ;
  370.   }
  371.  
  372.  /***************************************************************************
  373.   * Create the frame window.                                                *
  374.   ***************************************************************************/
  375.  
  376.   FRAMECDATA FrameControlData ;
  377.   FrameControlData.cb = sizeof(FrameControlData) ;
  378.   FrameControlData.flCreateFlags =
  379.     FCF_TITLEBAR | FCF_SYSMENU | FCF_BORDER |
  380.     FCF_ICON | FCF_MINBUTTON | FCF_NOBYTEALIGN | FCF_ACCELTABLE ;
  381.   FrameControlData.hmodResources = 0 ;
  382.   FrameControlData.idResources = ID_MAIN ;
  383.  
  384.   Window Frame ( HWND_DESKTOP, WC_FRAME, PSZ(Title),
  385.     Animate ? WS_ANIMATE : 0, 
  386.     0, 0, 0, 0, HWND_DESKTOP, HWND_TOP, ID_MAIN,
  387.     &FrameControlData, NULL ) ;
  388.  
  389.   if ( Frame.QueryHandle() == 0 ) {
  390.     ERRORID Error = WinGetLastError ( Proc.QueryAnchor() ) ;
  391.     ResourceString Format ( Library.QueryHandle(), IDS_ERROR_CREATEFRAME ) ;
  392.     CHAR Message [200] ;
  393.     sprintf ( Message, PCHAR(Format), Error ) ;
  394.     Log ( "%s", Message ) ;
  395.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
  396.       PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  397.     abort ( ) ;
  398.   }
  399.  
  400.  /***************************************************************************
  401.   * Associate the help instance with the frame window.                      *
  402.   ***************************************************************************/
  403.  
  404.   if ( Help.QueryHandle() ) {
  405.     WinAssociateHelpInstance ( Help.QueryHandle(), Frame.QueryHandle() ) ;
  406.   }
  407.  
  408.  /***************************************************************************
  409.   * Register the client window class.                                       *
  410.   ***************************************************************************/
  411.  
  412.   if
  413.   (
  414.     !WinRegisterClass
  415.     (
  416.       Proc.QueryAnchor(),
  417.       PSZ(CLASS_NAME),
  418.       MessageProcessor,
  419.       CS_MOVENOTIFY,
  420.       sizeof(PVOID)
  421.     )
  422.   )
  423.   {
  424.     ERRORID Error = WinGetLastError ( Proc.QueryAnchor() ) ;
  425.     ResourceString Format ( Library.QueryHandle(), IDS_ERROR_WINREGISTERCLASS ) ;
  426.     CHAR Message [200] ;
  427.     sprintf ( Message, PCHAR(Format), CLASS_NAME, Error ) ;
  428.     Log ( "%s", Message ) ;
  429.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
  430.       PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  431.     abort ( ) ;
  432.   }
  433.  
  434.  /***************************************************************************
  435.   * Create the client window.                                               *
  436.   ***************************************************************************/
  437.  
  438.   PARMS Parms ;
  439.   Parms.Filler = 0 ;
  440.   Parms.Proc = & Proc ;
  441.   Parms.Library = & Library ;
  442.   Parms.IniFile = & IniFile ;
  443.  
  444.   Window Client ( Frame.QueryHandle(), PSZ(CLASS_NAME), PSZ(""), 0, 0, 0, 0, 0,
  445.      Frame.QueryHandle(), HWND_BOTTOM, FID_CLIENT, &Parms, NULL ) ;
  446.  
  447.   if ( Client.QueryHandle() == 0 ) {
  448.     ERRORID Error = WinGetLastError ( Proc.QueryAnchor() ) ;
  449.     ResourceString Format ( Library.QueryHandle(), IDS_ERROR_CREATECLIENT ) ;
  450.     CHAR Message [200] ;
  451.     sprintf ( Message, PCHAR(Format), Error ) ;
  452.     Log ( "%s", Message ) ;
  453.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
  454.       PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  455.     abort ( ) ;
  456.   }
  457.  
  458.  /***************************************************************************
  459.   * Wait for and process messages to the window's queue.  Terminate         *
  460.   *   when the WM_QUIT message is received.                                 *
  461.   ***************************************************************************/
  462.  
  463.   QMSG QueueMessage ;
  464.   while ( WinGetMsg ( Proc.QueryAnchor(), &QueueMessage, 0, 0, 0 ) ) {
  465.     WinDispatchMsg ( Proc.QueryAnchor(), &QueueMessage ) ;
  466.   }
  467.  
  468.  /***************************************************************************
  469.   * Discard all that was requested of the system and terminate.             *
  470.   ***************************************************************************/
  471.  
  472.   return ( 0 ) ;
  473. }
  474.  
  475. /****************************************************************************
  476.  *                                                                          *
  477.  *      Window Message Processor                                            *
  478.  *                                                                          *
  479.  ****************************************************************************/
  480.  
  481. STATIC MRESULT EXPENTRY MessageProcessor ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  482.  
  483.  /***************************************************************************
  484.   * Dispatch the message according to the method table and return the       *
  485.   *   result.  Any messages not defined above get handled by the system     *
  486.   *   default window processor.                                             *
  487.   ***************************************************************************/
  488.  
  489.   static METHOD Methods [] =
  490.   {
  491.     { WM_CREATE,                Create              },
  492.     { WM_DESTROY,               Destroy             },
  493.     { WM_SIZE,                  Size                },
  494.     { WM_MOVE,                  Size                },
  495.     { WM_SAVEAPPLICATION,       SaveApplication     },
  496.     { WM_PAINT,                 Paint               },
  497.     { WM_BUTTON1DOWN,           ButtonDown          },
  498.     { WM_BUTTON2DOWN,           ButtonDown          },
  499.     { WM_BUTTON1DBLCLK,         ButtonDblClick      },
  500.     { WM_BUTTON2DBLCLK,         ButtonDblClick      },
  501.     { WM_PRESPARAMCHANGED,      PresParamChanged    },
  502.     { WM_SYSCOLORCHANGE,        SysColorChange      },
  503.     { WM_COMMAND,               Command             },
  504.     { HM_QUERY_KEYS_HELP,       QueryKeysHelp       },
  505.     { HM_ERROR,                 HelpError           },
  506.     { HM_EXT_HELP_UNDEFINED,    ExtHelpUndefined    },
  507.     { HM_HELPSUBITEM_NOT_FOUND, HelpSubitemNotFound },
  508.     { WM_REFRESH,               Refresh             }
  509.   } ;
  510.  
  511.   return ( DispatchMessage ( hwnd, msg, mp1, mp2, Methods, sizeof(Methods)/sizeof(Methods[0]), WinDefWindowProc ) ) ;
  512. }
  513.  
  514. /****************************************************************************
  515.  *                                                                          *
  516.  *      Create the main window.                                             *
  517.  *                                                                          *
  518.  ****************************************************************************/
  519.  
  520. STATIC MRESULT APIENTRY Create ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  521.  
  522.  /***************************************************************************
  523.   * Allocate instance data.                                                 *
  524.   ***************************************************************************/
  525.  
  526.   PDATA Data = PDATA ( malloc ( sizeof(DATA) ) ) ;
  527.  
  528.   memset ( Data, 0, sizeof(DATA) ) ;
  529.  
  530.   WinSetWindowPtr ( hwnd, QWL_USER, Data ) ;
  531.  
  532.  /***************************************************************************
  533.   * Grab any parameters from the WM_CREATE message.                         *
  534.   ***************************************************************************/
  535.  
  536.   PPARMS Parms = (PPARMS) PVOIDFROMMP ( mp1 ) ;
  537.  
  538.   Data->Proc = Parms->Proc ;
  539.   Data->Library = Parms->Library ;
  540.   Data->IniFile = Parms->IniFile ;
  541.  
  542.  /***************************************************************************
  543.   * Get the current drive mask.                                             *
  544.   ***************************************************************************/
  545.  
  546.   ULONG Drive ;
  547.   DosQueryCurrentDisk ( &Drive, &Data->Drives ) ;
  548.  
  549.  /***************************************************************************
  550.   * Calibrate the old-style load meter, if the high resolution timer's      *
  551.   *   available.                                                            *
  552.   ***************************************************************************/
  553.  
  554.   Data->IniData.MaxCount = CalibrateLoadMeter ( &Data->IdleLoopParms ) ;
  555.   Data->IniData.MaxCount = (ULONG) max ( 1, Data->IniData.MaxCount ) ;
  556.  
  557.  /***************************************************************************
  558.   * Get profile data. Try the OS2.INI first, then try for private INI.      *
  559.   *   If obtained from OS2.INI, erase it afterwards.                        *
  560.   ***************************************************************************/
  561.  
  562.   if ( GetIniData ( Data->Proc->QueryAnchor(), Data->Library->QueryHandle(), HINI_USERPROFILE, &Data->IniData ) ) {
  563.     GetIniData ( Data->Proc->QueryAnchor(), Data->Library->QueryHandle(), Data->IniFile->QueryHandle(), &Data->IniData ) ;
  564.   } else {
  565.     PrfWriteProfileData ( HINI_USERPROFILE, PSZ(PROGRAM_NAME), 0, 0, 0 ) ;
  566.   }
  567.  
  568.  /***************************************************************************
  569.   * Get the frame handle.                                                   *
  570.   ***************************************************************************/
  571.  
  572.   HWND hwndFrame = WinQueryWindow ( hwnd, QW_PARENT ) ;
  573.  
  574.  /***************************************************************************
  575.   * Get the control window handles.                                         *
  576.   ***************************************************************************/
  577.  
  578.   Data->hwndSysMenu  = WinWindowFromID ( hwndFrame, FID_SYSMENU  ) ;
  579.   Data->hwndTitleBar = WinWindowFromID ( hwndFrame, FID_TITLEBAR ) ;
  580.   Data->hwndMinMax   = WinWindowFromID ( hwndFrame, FID_MINMAX   ) ;
  581.  
  582.  /***************************************************************************
  583.   * Add basic extensions to the system menu.                                *
  584.   ***************************************************************************/
  585.  
  586.   static MENUITEM MenuSeparator =
  587.     { MIT_END, MIS_SEPARATOR, 0, 0, 0, 0 } ;
  588.  
  589.   AddSysMenuItem ( hwndFrame, &MenuSeparator, 0 ) ;
  590.  
  591.   static MENUITEM MenuItems [] =
  592.   {
  593.     { MIT_END, MIS_TEXT,      0, IDM_SAVE_APPLICATION, 0, 0 },
  594.     { MIT_END, MIS_TEXT,      0, IDM_RESET_DEFAULTS,   0, 0 },
  595.     { MIT_END, MIS_TEXT,      0, IDM_HIDE_CONTROLS,    0, 0 },
  596.     { MIT_END, MIS_TEXT,      0, IDM_CONFIGURE,        0, 0 },
  597.   } ;
  598.  
  599.   for ( int i=0; i<sizeof(MenuItems)/sizeof(MenuItems[0]); i++ ) {
  600.     ResourceString MenuText ( Data->Library->QueryHandle(), i+IDS_SAVE_APPLICATION ) ;
  601.     AddSysMenuItem ( hwndFrame, MenuItems+i, PSZ(MenuText) ) ;
  602.   }
  603.  
  604.   AddSysMenuItem ( hwndFrame, &MenuSeparator, 0 ) ;
  605.  
  606.  /***************************************************************************
  607.   * Add 'About' to the system menu.                                         *
  608.   ***************************************************************************/
  609.  
  610.   static MENUITEM MenuAbout =
  611.     { MIT_END, MIS_TEXT, 0, IDM_ABOUT, 0, 0 } ;
  612.  
  613.   ResourceString AboutText ( Data->Library->QueryHandle(), IDS_ABOUT ) ;
  614.  
  615.   AddSysMenuItem ( hwndFrame, &MenuAbout, PSZ(AboutText) ) ;
  616.  
  617.  /***************************************************************************
  618.   * Add 'Help' to the system menu.                                          *
  619.   ***************************************************************************/
  620.  
  621.   static MENUITEM MenuHelp =
  622.     { MIT_END, MIS_HELP, 0, 0, 0, 0 } ;
  623.  
  624.   ResourceString HelpText ( Data->Library->QueryHandle(), IDS_HELP ) ;
  625.  
  626.   AddSysMenuItem ( hwndFrame, &MenuHelp, PSZ(HelpText) ) ;
  627.  
  628.  /***************************************************************************
  629.   * Start the new load meter.                                               *
  630.   ***************************************************************************/
  631.  
  632.   Data->IdleLoopParms.Active = TRUE ;
  633.   Data->IdleLoopTID = _beginthread ( CounterThread, NULL, 0x3000, &Data->IdleLoopParms ) ;
  634.   DosSuspendThread ( Data->IdleLoopTID ) ;
  635.   DosSetPriority ( PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MINIMUM, Data->IdleLoopTID ) ;
  636.  
  637.   Data->IniData.IdleCount = 0 ;
  638.   Data->IdleLoopParms.Counter = 0 ;
  639.  
  640.   if ( Data->IniData.Items[ITEM_CPULOAD]->QueryFlag() ) {
  641.     DosResumeThread ( Data->IdleLoopTID ) ;
  642.   }
  643.  
  644.   Data->MonitorParms.Active = TRUE ;
  645.   Data->MonitorParms.Counter = & Data->IdleLoopParms.Counter ;
  646.   Data->MonitorParms.Interval = & Data->IniData.TimerInterval ;
  647.   Data->MonitorParms.Priority = & Data->IniData.MonitorPriority ;
  648.   Data->MonitorParms.Owner = hwnd ;
  649.   Data->MonitorTID = _beginthread ( MonitorLoopThread, NULL, 0x3000, &Data->MonitorParms ) ;
  650.  
  651.  /***************************************************************************
  652.   * Add the program to the system task list.                                *
  653.   ***************************************************************************/
  654.  
  655.   ResourceString Title ( Data->Library->QueryHandle(), IDS_TITLE ) ;
  656.   Add2TaskList ( hwndFrame, PSZ(Title) ) ;
  657.  
  658.  /***************************************************************************
  659.   * Position & size the window.  For some reason, we must move and size     *
  660.   *   the window to the saved position before applying the resizing         *
  661.   *   function as fine-tuning.  Maybe the positioning request fails if      *
  662.   *   the window has no size?                                               *
  663.   ***************************************************************************/
  664.  
  665.   WinSetWindowPos ( hwndFrame, HWND_BOTTOM,
  666.     Data->IniData.Position.x, Data->IniData.Position.y,
  667.     Data->IniData.Position.cx, Data->IniData.Position.cy,
  668.     SWP_SIZE | SWP_MOVE | SWP_ZORDER |
  669.     ( Data->IniData.Position.fl & SWP_MINIMIZE ) |
  670.     ( Data->IniData.Position.fl & SWP_RESTORE ) ) ;
  671.  
  672.   ResizeWindow ( hwnd, &Data->IniData ) ;
  673.  
  674.  /***************************************************************************
  675.   * Hide the controls if so configured.                                     *
  676.   ***************************************************************************/
  677.  
  678.   if ( Data->IniData.HideControls
  679.     AND NOT ( Data->IniData.Position.fl & SWP_MINIMIZE ) ) {
  680.  
  681.     CheckMenuItem ( hwndFrame, FID_SYSMENU, IDM_HIDE_CONTROLS, Data->IniData.HideControls ) ;
  682.  
  683.     HideControls
  684.     (
  685.       TRUE,
  686.       hwndFrame,
  687.       Data->hwndSysMenu,
  688.       Data->hwndTitleBar,
  689.       Data->hwndMinMax
  690.     ) ;
  691.   }
  692.  
  693.  /***************************************************************************
  694.   * Get the saved presentation parameters and reinstate them.               *
  695.   ***************************************************************************/
  696.  
  697.   if ( Data->IniData.fFontNameSize ) {
  698.     WinSetPresParam ( hwnd, PP_FONTNAMESIZE,
  699.       strlen(PCHAR(Data->IniData.FontNameSize))+1, Data->IniData.FontNameSize ) ;
  700.   }
  701.  
  702.   if ( Data->IniData.fBackColor ) {
  703.     WinSetPresParam ( hwnd, PP_BACKGROUNDCOLOR,
  704.       sizeof(Data->IniData.BackColor), &Data->IniData.BackColor ) ;
  705.   }
  706.  
  707.   if ( Data->IniData.fTextColor ) {
  708.     WinSetPresParam ( hwnd, PP_FOREGROUNDCOLOR,
  709.       sizeof(Data->IniData.TextColor), &Data->IniData.TextColor ) ;
  710.   }
  711.  
  712.  /***************************************************************************
  713.   * Determine our font size.                                                *
  714.   ***************************************************************************/
  715.  
  716.   HPS hPS = WinGetPS ( hwnd ) ;
  717.   RECTL Rectangle ;
  718.   WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  719.   WinDrawText ( hPS, 1, PSZ(" "), &Rectangle, 0L, 0L, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  720.   Data->Width  = Rectangle.xRight - Rectangle.xLeft ;
  721.   Data->Height = Rectangle.yTop - Rectangle.yBottom ;
  722.   WinReleasePS ( hPS ) ;
  723.  
  724.  /***************************************************************************
  725.   * Now that the window's in order, make it visible.                        *
  726.   ***************************************************************************/
  727.  
  728.   WinShowWindow ( hwndFrame, TRUE ) ;
  729.  
  730.  /***************************************************************************
  731.   * Success?  Return no error.                                              *
  732.   ***************************************************************************/
  733.  
  734.   return ( 0 ) ;
  735. }
  736.  
  737. /****************************************************************************
  738.  *                                                                          *
  739.  *      Destroy main window.                                                *
  740.  *                                                                          *
  741.  ****************************************************************************/
  742.  
  743. STATIC MRESULT APIENTRY Destroy ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  744.  
  745.  /***************************************************************************
  746.   * Find the instance data.                                                 *
  747.   ***************************************************************************/
  748.  
  749.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  750.  
  751.  /***************************************************************************
  752.   * Kill the extra threads.                                                 *
  753.   ***************************************************************************/
  754.  
  755.   DosResumeThread ( Data->MonitorTID ) ;
  756.   Data->MonitorParms.Active = FALSE ;
  757.   DosWaitThread ( &Data->MonitorTID, DCWW_WAIT ) ;
  758.  
  759.   DosResumeThread ( Data->IdleLoopTID ) ;
  760.   Data->IdleLoopParms.Active = FALSE ;
  761.   DosSetPriority ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, Data->IdleLoopTID ) ;
  762.   DosWaitThread ( &Data->IdleLoopTID, DCWW_WAIT ) ;
  763.  
  764.  /***************************************************************************
  765.   * Release the instance memory.                                            *
  766.   ***************************************************************************/
  767.  
  768.   free ( Data ) ;
  769.  
  770.  /***************************************************************************
  771.   * We're done.                                                             *
  772.   ***************************************************************************/
  773.  
  774.   return ( MRFROMSHORT ( 0 ) ) ;
  775. }
  776.  
  777. /****************************************************************************
  778.  *                                                                          *
  779.  *      Process window resize message.                                      *
  780.  *                                                                          *
  781.  ****************************************************************************/
  782.  
  783. STATIC MRESULT APIENTRY Size ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  784.  
  785.  /***************************************************************************
  786.   * Find the instance data.                                                 *
  787.   ***************************************************************************/
  788.  
  789.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  790.  
  791.  /***************************************************************************
  792.   * Find out the window's new position and size.                            *
  793.   ***************************************************************************/
  794.  
  795.   HWND hwndFrame = WinQueryWindow ( hwnd, QW_PARENT ) ;
  796.  
  797.   SWP Position ;
  798.   WinQueryWindowPos ( hwndFrame, &Position ) ;
  799.  
  800.   if ( NOT ( Position.fl & SWP_MINIMIZE )
  801.     AND NOT ( Position.fl & SWP_MAXIMIZE ) ) {
  802.  
  803.     Data->IniData.Position.x = Position.x ;
  804.     Data->IniData.Position.y = Position.y ;
  805.  
  806.     Data->IniData.Position.cx = Position.cx ;
  807.     Data->IniData.Position.cy = Position.cy ;
  808.   }
  809.  
  810.  /***************************************************************************
  811.   * If hiding the controls . . .                                            *
  812.   ***************************************************************************/
  813.  
  814.   if ( Data->IniData.HideControls ) {
  815.  
  816.    /*************************************************************************
  817.     * If changing to or from minimized state . . .                          *
  818.     *************************************************************************/
  819.  
  820.     if ( ( Position.fl & SWP_MINIMIZE ) != ( Data->IniData.Position.fl & SWP_MINIMIZE ) )
  821.     {
  822.  
  823.      /***********************************************************************
  824.       * Hide the controls if no longer minimized.                           *
  825.       ***********************************************************************/
  826.  
  827.       HideControls
  828.       (
  829.         NOT ( Position.fl & SWP_MINIMIZE ),
  830.         hwndFrame,
  831.         Data->hwndSysMenu,
  832.         Data->hwndTitleBar,
  833.         Data->hwndMinMax
  834.       ) ;
  835.     }
  836.   }
  837.  
  838.   Data->IniData.Position.fl = Position.fl ;
  839.  
  840.  /***************************************************************************
  841.   * We're done.                                                             *
  842.   ***************************************************************************/
  843.  
  844.   return ( 0 ) ;
  845. }
  846.  
  847. /****************************************************************************
  848.  *                                                                          *
  849.  *      Process SAVE APPLICATION message.                                   *
  850.  *                                                                          *
  851.  ****************************************************************************/
  852.  
  853. STATIC MRESULT APIENTRY SaveApplication ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  854.  
  855.  /***************************************************************************
  856.   * Find the instance data.                                                 *
  857.   ***************************************************************************/
  858.  
  859.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  860.  
  861.  /***************************************************************************
  862.   * Call function to put all profile data out to the system.                *
  863.   ***************************************************************************/
  864.  
  865.   PutIniData ( Data->IniFile->QueryHandle(), &Data->IniData ) ;
  866.  
  867.  /***************************************************************************
  868.   * We're done.  Let the system complete default processing.                *
  869.   ***************************************************************************/
  870.  
  871.   return ( WinDefWindowProc ( hwnd, WM_SAVEAPPLICATION, 0, 0 ) ) ;
  872. }
  873.  
  874. /****************************************************************************
  875.  *                                                                          *
  876.  *      Repaint entire window.                                              *
  877.  *                                                                          *
  878.  ****************************************************************************/
  879.  
  880. STATIC MRESULT APIENTRY Paint ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  881.  
  882.  /***************************************************************************
  883.   * Find the instance data.                                                 *
  884.   ***************************************************************************/
  885.  
  886.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  887.  
  888.  /***************************************************************************
  889.   * Get presentation space and make it use RGB colors.                      *
  890.   ***************************************************************************/
  891.  
  892.   HPS hPS = WinBeginPaint ( hwnd, HPS(NULL), PRECTL(NULL) ) ;
  893.   GpiCreateLogColorTable ( hPS, LCOL_RESET, LCOLF_RGB, 0L, 0L, PLONG(NULL) ) ;
  894.  
  895.  /***************************************************************************
  896.   * Clear the window.                                                       *
  897.   ***************************************************************************/
  898.  
  899.   RECTL Rectangle ;
  900.   WinQueryWindowRect ( hwnd, &Rectangle ) ;
  901.  
  902.   GpiMove ( hPS, (PPOINTL) &Rectangle.xLeft ) ;
  903.   GpiSetColor ( hPS, Data->IniData.BackColor ) ;
  904.   GpiBox ( hPS, DRO_FILL, (PPOINTL) &Rectangle.xRight, 0L, 0L ) ;
  905.  
  906.  /***************************************************************************
  907.   * Release presentation space.                                             *
  908.   ***************************************************************************/
  909.  
  910.   WinEndPaint ( hPS ) ;
  911.  
  912.  /***************************************************************************
  913.   * Update the window and return.                                           *
  914.   ***************************************************************************/
  915.  
  916.   UpdateWindow ( hwnd, Data, TRUE ) ;
  917.  
  918.   return ( 0 ) ;
  919. }
  920.  
  921. /****************************************************************************
  922.  *                                                                          *
  923.  *      Process commands received by Main Window                            *
  924.  *                                                                          *
  925.  ****************************************************************************/
  926.  
  927. STATIC MRESULT APIENTRY Command ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  928.  
  929.  /***************************************************************************
  930.   * Dispatch all other commands through the method table.                   *
  931.   ***************************************************************************/
  932.  
  933.   static METHOD Methods [] =
  934.   {
  935.     { IDM_SAVE_APPLICATION, SaveApplication },
  936.     { IDM_RESET_DEFAULTS,   ResetDefaults   },
  937.     { IDM_HIDE_CONTROLS,    HideControlsCmd },
  938.     { IDM_CONFIGURE,        Configure       },
  939.     { IDM_EXIT,             Exit            },
  940.     { IDM_ABOUT,            About           },
  941.   } ;
  942.  
  943.   return ( DispatchMessage ( hwnd, SHORT1FROMMP(mp1), mp1, mp2, Methods, sizeof(Methods)/sizeof(Methods[0]), PFNWP(NULL) ) ) ;
  944. }
  945.  
  946. /****************************************************************************
  947.  *                                                                          *
  948.  *      Process Reset Defaults menu command.                                *
  949.  *                                                                          *
  950.  ****************************************************************************/
  951.  
  952. STATIC MRESULT APIENTRY ResetDefaults ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  953.  
  954.  /***************************************************************************
  955.   * Find the instance data.                                                 *
  956.   ***************************************************************************/
  957.  
  958.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  959.  
  960.  /***************************************************************************
  961.   * Reset all profile data for this program.                                *
  962.   ***************************************************************************/
  963.  
  964.   PrfWriteProfileData ( Data->IniFile->QueryHandle(), PSZ(PROGRAM_NAME), 0, 0, 0 ) ;
  965.  
  966.  /***************************************************************************
  967.   * Reset the program's presentation parameters.                            *
  968.   ***************************************************************************/
  969.  
  970.   WinRemovePresParam ( hwnd, PP_FONTNAMESIZE ) ;
  971.   WinRemovePresParam ( hwnd, PP_FOREGROUNDCOLOR ) ;
  972.   WinRemovePresParam ( hwnd, PP_BACKGROUNDCOLOR ) ;
  973.  
  974.  /***************************************************************************
  975.   * Done.                                                                   *
  976.   ***************************************************************************/
  977.  
  978.   return ( MRFROMSHORT ( 0 ) ) ;
  979. }
  980.  
  981. /****************************************************************************
  982.  *                                                                          *
  983.  *      Process Hide Controls menu command.                                 *
  984.  *                                                                          *
  985.  ****************************************************************************/
  986.  
  987. STATIC MRESULT APIENTRY HideControlsCmd ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  988.  
  989.  /***************************************************************************
  990.   * Find the instance data.                                                 *
  991.   ***************************************************************************/
  992.  
  993.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  994.  
  995.  /***************************************************************************
  996.   * Toggle the Hide Controls setting.                                       *
  997.   ***************************************************************************/
  998.  
  999.   Data->IniData.HideControls = Data->IniData.HideControls ? FALSE : TRUE ;
  1000.   Data->IniData.fHideControls = TRUE ;
  1001.  
  1002.  /***************************************************************************
  1003.   * Get the frame handle.                                                   *
  1004.   ***************************************************************************/
  1005.  
  1006.   HWND hwndFrame = WinQueryWindow ( hwnd, QW_PARENT ) ;
  1007.  
  1008.  /***************************************************************************
  1009.   * If controls aren't hidden yet, update the menu check-mark.              *
  1010.   ***************************************************************************/
  1011.  
  1012.   if ( Data->IniData.HideControls )
  1013.     CheckMenuItem ( hwndFrame, FID_SYSMENU, IDM_HIDE_CONTROLS, Data->IniData.HideControls ) ;
  1014.  
  1015.  /***************************************************************************
  1016.   * If not minimized right now, hide or reveal the controls.                *
  1017.   ***************************************************************************/
  1018.  
  1019.   if ( NOT ( Data->IniData.Position.fl & SWP_MINIMIZE ) )
  1020.   {
  1021.     HideControls
  1022.     (
  1023.       Data->IniData.HideControls,
  1024.       hwndFrame,
  1025.       Data->hwndSysMenu,
  1026.       Data->hwndTitleBar,
  1027.       Data->hwndMinMax
  1028.     ) ;
  1029.   }
  1030.  
  1031.  /***************************************************************************
  1032.   * If controls are no longer hidden, update the menu check-mark.           *
  1033.   ***************************************************************************/
  1034.  
  1035.   if ( NOT Data->IniData.HideControls )
  1036.     CheckMenuItem ( hwndFrame, FID_SYSMENU, IDM_HIDE_CONTROLS, Data->IniData.HideControls ) ;
  1037.  
  1038.  /***************************************************************************
  1039.   * Done.                                                                   *
  1040.   ***************************************************************************/
  1041.  
  1042.   return ( MRFROMSHORT ( 0 ) ) ;
  1043. }
  1044.  
  1045. /****************************************************************************
  1046.  *                                                                          *
  1047.  *      Process Configure command.                                          *
  1048.  *                                                                          *
  1049.  ****************************************************************************/
  1050.  
  1051. STATIC MRESULT APIENTRY Configure ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1052.  
  1053.  /***************************************************************************
  1054.   * Find the instance data.                                                 *
  1055.   ***************************************************************************/
  1056.  
  1057.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1058.  
  1059.  /***************************************************************************
  1060.   * Invoke the Configure dialog.  If cancelled, just return.                *
  1061.   ***************************************************************************/
  1062.  
  1063.   CONFIG_PARMS Parms ;
  1064.   Parms.id                  = IDD_CONFIGURE ;
  1065.   Parms.hwndHelp            = WinQueryHelpInstance ( hwnd ) ;
  1066.   Parms.HideControls        = Data->IniData.HideControls ;
  1067.   Parms.Float               = Data->IniData.Float ;
  1068.   Parms.Animate             = Data->IniData.Animate ;
  1069.   Parms.ShowFileSystemNames = Data->IniData.ShowFileSystemNames ;
  1070.   Parms.ShowDiskLabels      = Data->IniData.ShowDiskLabels ;
  1071.   Parms.MonitorPriority     = Data->IniData.MonitorPriority ;
  1072.   Parms.TimerInterval       = Data->IniData.TimerInterval ;
  1073.  
  1074.   Parms.ItemCount           = Data->IniData.ItemCount ;
  1075.  
  1076.   PSZ  ItemNames [ ITEM_BASE_COUNT + MAX_DRIVES ] ;
  1077.   BOOL ItemFlags [ ITEM_BASE_COUNT + MAX_DRIVES ] ;
  1078.   for ( int i=0; i<Data->IniData.ItemCount; i++ )
  1079.   {
  1080.     ItemNames[i] = Data->IniData.Items[i]->QueryOption () ;
  1081.     ItemFlags[i] = Data->IniData.Items[i]->QueryFlag () ;
  1082.   }
  1083.   Parms.ItemNames = ItemNames ;
  1084.   Parms.ItemFlags = ItemFlags ;
  1085.  
  1086.   if ( WinDlgBox ( HWND_DESKTOP, hwnd, PFNWP(ConfigureProcessor),
  1087.     Data->Library->QueryHandle(), IDD_CONFIGURE, &Parms ) == FALSE )
  1088.   {
  1089.     return ( MRFROMSHORT ( 0 ) ) ;
  1090.   }
  1091.  
  1092.  /***************************************************************************
  1093.   * Save the new monitor priority.                                          *
  1094.   ***************************************************************************/
  1095.  
  1096.   Data->IniData.fMonitorPriority = TRUE ;
  1097.   Data->IniData.MonitorPriority = Parms.MonitorPriority ;
  1098.  
  1099.  /***************************************************************************
  1100.   * Save the new timer interval.                                            *
  1101.   ***************************************************************************/
  1102.  
  1103.   Data->IniData.fTimerInterval = TRUE ;
  1104.   Data->IniData.TimerInterval = Parms.TimerInterval ;
  1105.  
  1106.  /***************************************************************************
  1107.   * Save the float-to-top flag.                                             *
  1108.   ***************************************************************************/
  1109.  
  1110.   Data->IniData.fFloat = TRUE ;
  1111.   Data->IniData.Float = Parms.Float ;
  1112.  
  1113.  /***************************************************************************
  1114.   * Save the window animate flag.                                           *
  1115.   ***************************************************************************/
  1116.  
  1117.   Data->IniData.fAnimate = TRUE ;
  1118.   Data->IniData.Animate = Parms.Animate ;
  1119.  
  1120.  /***************************************************************************
  1121.   * Save the hide controls flag, and adjust the window if it changed.       *
  1122.   ***************************************************************************/
  1123.  
  1124.   Data->IniData.fHideControls = TRUE ;
  1125.   if ( Data->IniData.HideControls != Parms.HideControls ) {
  1126.     HWND FrameWindow = WinQueryWindow ( hwnd, QW_PARENT ) ;
  1127.     Data->IniData.HideControls = Parms.HideControls ;
  1128.     if ( Data->IniData.HideControls )
  1129.       CheckMenuItem ( FrameWindow, FID_SYSMENU, IDM_HIDE_CONTROLS, Data->IniData.HideControls ) ;
  1130.     if ( NOT ( Data->IniData.Position.fl & SWP_MINIMIZE ) ) {
  1131.       HideControls
  1132.       (
  1133.         Data->IniData.HideControls,
  1134.         FrameWindow,
  1135.         Data->hwndSysMenu,
  1136.         Data->hwndTitleBar,
  1137.         Data->hwndMinMax
  1138.       ) ;
  1139.     }
  1140.     if ( NOT Data->IniData.HideControls )
  1141.       CheckMenuItem ( FrameWindow, FID_SYSMENU, IDM_HIDE_CONTROLS, Data->IniData.HideControls ) ;
  1142.   }
  1143.  
  1144.  /***************************************************************************
  1145.   * Determine if the display item list has changed.  If not, return.        *
  1146.   ***************************************************************************/
  1147.  
  1148.   BOOL ItemsChanged = FALSE ;
  1149.   for ( i=0; i<Data->IniData.ItemCount; i++ ) {
  1150.     if ( ItemFlags[i] != Data->IniData.Items[i]->QueryFlag() ) {
  1151.       ItemsChanged = TRUE ;
  1152.       break ;
  1153.     }
  1154.   }
  1155.  
  1156.   if ( NOT ItemsChanged 
  1157.      AND ( Data->IniData.ShowFileSystemNames == Parms.ShowFileSystemNames ) 
  1158.      AND ( Data->IniData.ShowDiskLabels == Parms.ShowDiskLabels ) ) {
  1159.      return ( MRFROMSHORT ( 0 ) ) ;
  1160.   }
  1161.  
  1162.  /***************************************************************************
  1163.   * Save the show file-system names flag.                                   *
  1164.   ***************************************************************************/
  1165.  
  1166.   Data->IniData.fShowFileSystemNames = TRUE ;
  1167.   Data->IniData.ShowFileSystemNames = Parms.ShowFileSystemNames ;
  1168.  
  1169.   for ( i=ITEM_BASE_COUNT; i<Data->IniData.ItemCount; i++ ) {
  1170.      ((DriveFree*)Data->IniData.Items[i])->SetShowFileSystemName ( Data->IniData.ShowFileSystemNames ) ;
  1171.   } /* endfor */
  1172.  
  1173.  /***************************************************************************
  1174.   * Save the show disk labels flag.                                         *
  1175.   ***************************************************************************/
  1176.  
  1177.   Data->IniData.fShowDiskLabels = TRUE ;
  1178.   Data->IniData.ShowDiskLabels = Parms.ShowDiskLabels ;
  1179.  
  1180.   for ( i=ITEM_BASE_COUNT; i<Data->IniData.ItemCount; i++ ) {
  1181.      ((DriveFree*)Data->IniData.Items[i])->SetShowDiskLabel ( Data->IniData.ShowDiskLabels ) ;
  1182.   } /* endfor */
  1183.  
  1184.  /***************************************************************************
  1185.   * If CPU load monitoring has changed, start/stop the monitoring thread.   *
  1186.   ***************************************************************************/
  1187.  
  1188.   if ( ItemFlags[ITEM_CPULOAD] != Data->IniData.Items[ITEM_CPULOAD]->QueryFlag() ) {
  1189.     if ( ItemFlags[ITEM_CPULOAD] )
  1190.       DosResumeThread ( Data->IdleLoopTID ) ;
  1191.     else
  1192.       DosSuspendThread ( Data->IdleLoopTID ) ;
  1193.   }
  1194.  
  1195.  /***************************************************************************
  1196.   * Save the new item flags.                                                *
  1197.   ***************************************************************************/
  1198.  
  1199.   for ( i=0; i<Data->IniData.ItemCount; i++ ) {
  1200.     if ( ItemFlags[i] )
  1201.       Data->IniData.Items[i]->SetFlag ( ) ;
  1202.     else
  1203.       Data->IniData.Items[i]->ResetFlag ( ) ;
  1204.   }
  1205.  
  1206.  /***************************************************************************
  1207.   * Resize the display window.                                              *
  1208.   ***************************************************************************/
  1209.  
  1210.   ResizeWindow ( hwnd, &Data->IniData ) ;
  1211.  
  1212.  /***************************************************************************
  1213.   * Done.                                                                   *
  1214.   ***************************************************************************/
  1215.  
  1216.   return ( MRFROMSHORT ( 0 ) ) ;
  1217. }
  1218.  
  1219. /****************************************************************************
  1220.  *                                                                          *
  1221.  *      Process About menu command.                                         *
  1222.  *                                                                          *
  1223.  ****************************************************************************/
  1224.  
  1225. STATIC MRESULT APIENTRY About ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1226.  
  1227.  /***************************************************************************
  1228.   * Find the instance data.                                                 *
  1229.   ***************************************************************************/
  1230.  
  1231.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1232.  
  1233.  /***************************************************************************
  1234.   * Invoke the About dialog.                                                *
  1235.   ***************************************************************************/
  1236.  
  1237.   ABOUT_PARMS Parms ;
  1238.   Parms.id = IDD_ABOUT ;
  1239.   Parms.hwndHelp = WinQueryHelpInstance ( hwnd ) ;
  1240.  
  1241.   WinDlgBox ( HWND_DESKTOP, hwnd, PFNWP(AboutProcessor),
  1242.     Data->Library->QueryHandle(), IDD_ABOUT, &Parms ) ;
  1243.  
  1244.  /***************************************************************************
  1245.   * Done.                                                                   *
  1246.   ***************************************************************************/
  1247.  
  1248.   return ( MRFROMSHORT ( 0 ) ) ;
  1249. }
  1250.  
  1251. /****************************************************************************
  1252.  *                                                                          *
  1253.  *      Process Mouse Button being pressed.                                 *
  1254.  *                                                                          *
  1255.  ****************************************************************************/
  1256.  
  1257. STATIC MRESULT APIENTRY ButtonDown ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1258.  
  1259.  /***************************************************************************
  1260.   * Find the instance data.                                                 *
  1261.   ***************************************************************************/
  1262.  
  1263.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1264.  
  1265.  /***************************************************************************
  1266.   * Determine the new window position.                                      *
  1267.   ***************************************************************************/
  1268.  
  1269.   TRACKINFO TrackInfo ;
  1270.   memset ( &TrackInfo, 0, sizeof(TrackInfo) ) ;
  1271.  
  1272.   TrackInfo.cxBorder = 1 ;
  1273.   TrackInfo.cyBorder = 1 ;
  1274.   TrackInfo.cxGrid = 1 ;
  1275.   TrackInfo.cyGrid = 1 ;
  1276.   TrackInfo.cxKeyboard = 8 ;
  1277.   TrackInfo.cyKeyboard = 8 ;
  1278.  
  1279.   HWND hwndFrame = WinQueryWindow ( hwnd, QW_PARENT ) ;
  1280.  
  1281.   SWP Position ;
  1282.   WinQueryWindowPos ( hwndFrame, &Position ) ;
  1283.   TrackInfo.rclTrack.xLeft   = Position.x ;
  1284.   TrackInfo.rclTrack.xRight  = Position.x + Position.cx ;
  1285.   TrackInfo.rclTrack.yBottom = Position.y ;
  1286.   TrackInfo.rclTrack.yTop    = Position.y + Position.cy ;
  1287.  
  1288.   WinQueryWindowPos ( HWND_DESKTOP, &Position ) ;
  1289.   TrackInfo.rclBoundary.xLeft   = Position.x ;
  1290.   TrackInfo.rclBoundary.xRight  = Position.x + Position.cx ;
  1291.   TrackInfo.rclBoundary.yBottom = Position.y ;
  1292.   TrackInfo.rclBoundary.yTop    = Position.y + Position.cy ;
  1293.  
  1294.   TrackInfo.ptlMinTrackSize.x = 0 ;
  1295.   TrackInfo.ptlMinTrackSize.y = 0 ;
  1296.   TrackInfo.ptlMaxTrackSize.x = Position.cx ;
  1297.   TrackInfo.ptlMaxTrackSize.y = Position.cy ;
  1298.  
  1299.   TrackInfo.fs = TF_MOVE | TF_STANDARD | TF_ALLINBOUNDARY ;
  1300.  
  1301.   if ( WinTrackRect ( HWND_DESKTOP, HPS(NULL), &TrackInfo ) )
  1302.   {
  1303.     WinSetWindowPos ( hwndFrame, 0,
  1304.       (SHORT) TrackInfo.rclTrack.xLeft,
  1305.       (SHORT) TrackInfo.rclTrack.yBottom,
  1306.       0, 0, SWP_MOVE ) ;
  1307.   }
  1308.  
  1309.  /***************************************************************************
  1310.   * Return through the default processor, letting window activation         *
  1311.   *   and other system functions occur.                                     *
  1312.   ***************************************************************************/
  1313.  
  1314.   return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
  1315. }
  1316.  
  1317. /****************************************************************************
  1318.  *                                                                          *
  1319.  *      Process Mouse Button having been double-clicked.                    *
  1320.  *                                                                          *
  1321.  ****************************************************************************/
  1322.  
  1323. STATIC MRESULT APIENTRY ButtonDblClick ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1324.  
  1325.  /***************************************************************************
  1326.   * Send message to self to stop hiding the controls.                       *
  1327.   ***************************************************************************/
  1328.  
  1329.   WinPostMsg ( hwnd, WM_COMMAND,
  1330.     MPFROM2SHORT ( IDM_HIDE_CONTROLS, 0 ),
  1331.     MPFROM2SHORT ( CMDSRC_OTHER, TRUE ) ) ;
  1332.  
  1333.  /***************************************************************************
  1334.   * Return through the default processor, letting window activation         *
  1335.   *   and other system functions occur.                                     *
  1336.   ***************************************************************************/
  1337.  
  1338.   return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
  1339. }
  1340.  
  1341. /****************************************************************************
  1342.  *                                                                          *
  1343.  *      Process Presentation Parameter Changed notification.                *
  1344.  *                                                                          *
  1345.  ****************************************************************************/
  1346.  
  1347. STATIC MRESULT APIENTRY PresParamChanged ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1348.  
  1349.  /***************************************************************************
  1350.   * Find the instance data.                                                 *
  1351.   ***************************************************************************/
  1352.  
  1353.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1354.  
  1355.  /***************************************************************************
  1356.   * Get the presentation parameter that changed.                            *
  1357.   ***************************************************************************/
  1358.  
  1359.   switch ( LONGFROMMP(mp1) )
  1360.   {
  1361.  
  1362.    /*************************************************************************
  1363.     * If font, note the fact that we now have a font to be saved as         *
  1364.     *   part of the configuration.  Get the font metrics and resize         *
  1365.     *   the window appropriately.                                           *
  1366.     *************************************************************************/
  1367.  
  1368.     case PP_FONTNAMESIZE:
  1369.     {
  1370.       ULONG ppid ;
  1371.       if ( WinQueryPresParam ( hwnd, PP_FONTNAMESIZE, 0, &ppid,
  1372.         sizeof(Data->IniData.FontNameSize), &Data->IniData.FontNameSize,
  1373.         0 ) )
  1374.       {
  1375.         Data->IniData.fFontNameSize = TRUE ;
  1376.       }
  1377.       else
  1378.       {
  1379.         strcpy ( PCHAR(Data->IniData.FontNameSize), "" ) ;
  1380.         Data->IniData.fFontNameSize = FALSE ;
  1381.         PrfWriteProfileData ( Data->IniFile->QueryHandle(), PSZ(PROGRAM_NAME), PSZ("FontNameSize"), NULL, 0 ) ;
  1382.       }
  1383.  
  1384.       HPS hPS = WinGetPS ( hwnd ) ;
  1385.       RECTL Rectangle ;
  1386.       WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  1387.       WinDrawText ( hPS, 1, PSZ(" "), &Rectangle, 0L, 0L, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  1388.       Data->Width  = Rectangle.xRight - Rectangle.xLeft ;
  1389.       Data->Height = Rectangle.yTop - Rectangle.yBottom ;
  1390.       WinReleasePS ( hPS ) ;
  1391.       ResizeWindow ( hwnd, &Data->IniData ) ;
  1392.       break ;
  1393.     }
  1394.  
  1395.    /*************************************************************************
  1396.     * If background color, note the fact and repaint the window.            *
  1397.     *************************************************************************/
  1398.  
  1399.     case PP_BACKGROUNDCOLOR:
  1400.     {
  1401.       ULONG ppid ;
  1402.       if ( WinQueryPresParam ( hwnd, PP_BACKGROUNDCOLOR, 0, &ppid,
  1403.         sizeof(Data->IniData.BackColor), &Data->IniData.BackColor, 0 ) )
  1404.       {
  1405.         Data->IniData.fBackColor = TRUE ;
  1406.       }
  1407.       else
  1408.       {
  1409.         Data->IniData.BackColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_WINDOW, 0L ) ;
  1410.         Data->IniData.fBackColor = FALSE ;
  1411.         PrfWriteProfileData ( Data->IniFile->QueryHandle(), PSZ(PROGRAM_NAME), PSZ("BackgroundColor"), NULL, 0 ) ;
  1412.       }
  1413.       WinInvalidateRect ( hwnd, PRECTL(NULL), TRUE ) ;
  1414.       break ;
  1415.     }
  1416.  
  1417.    /*************************************************************************
  1418.     * If foreground color, note the fact and repaint the window.            *
  1419.     *************************************************************************/
  1420.  
  1421.     case PP_FOREGROUNDCOLOR:
  1422.     {
  1423.       ULONG ppid ;
  1424.       if ( WinQueryPresParam ( hwnd, PP_FOREGROUNDCOLOR, 0, &ppid,
  1425.         sizeof(Data->IniData.TextColor), &Data->IniData.TextColor, 0 ) )
  1426.       {
  1427.         Data->IniData.fTextColor = TRUE ;
  1428.       }
  1429.       else
  1430.       {
  1431.         Data->IniData.TextColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0L ) ;
  1432.         Data->IniData.fTextColor = FALSE ;
  1433.         PrfWriteProfileData ( Data->IniFile->QueryHandle(), PSZ(PROGRAM_NAME), PSZ("ForegroundColor"), NULL, 0 ) ;
  1434.       }
  1435.       WinInvalidateRect ( hwnd, PRECTL(NULL), TRUE ) ;
  1436.       break ;
  1437.     }
  1438.   }
  1439.  
  1440.  /***************************************************************************
  1441.   * Return through the default processor, letting window activation         *
  1442.   *   and other system functions occur.                                     *
  1443.   ***************************************************************************/
  1444.  
  1445.   return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
  1446. }
  1447.  
  1448. /****************************************************************************
  1449.  *                                                                          *
  1450.  *      Process System Color Change notification.                           *
  1451.  *                                                                          *
  1452.  ****************************************************************************/
  1453.  
  1454. STATIC MRESULT APIENTRY SysColorChange ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1455.  
  1456.  /***************************************************************************
  1457.   * Find the instance data.                                                 *
  1458.   ***************************************************************************/
  1459.  
  1460.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1461.  
  1462.  /***************************************************************************
  1463.   * If we aren't using custom colors, then query for the new defaults.      *
  1464.   ***************************************************************************/
  1465.  
  1466.   if ( NOT Data->IniData.fBackColor )
  1467.   {
  1468.     Data->IniData.BackColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_WINDOW, 0L ) ;
  1469.   }
  1470.  
  1471.   if ( NOT Data->IniData.fTextColor )
  1472.   {
  1473.     Data->IniData.TextColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0L ) ;
  1474.   }
  1475.  
  1476.  /***************************************************************************
  1477.   * Return value must be NULL, according to the documentation.              *
  1478.   ***************************************************************************/
  1479.  
  1480.   return ( MRFROMP ( NULL ) ) ;
  1481. }
  1482.  
  1483. /****************************************************************************
  1484.  *                                                                          *
  1485.  *      Process Query for Keys Help resource id.                            *
  1486.  *                                                                          *
  1487.  ****************************************************************************/
  1488.  
  1489. STATIC MRESULT APIENTRY QueryKeysHelp ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1490.  
  1491.  /***************************************************************************
  1492.   * Simply return the ID of the Keys Help panel.                            *
  1493.   ***************************************************************************/
  1494.  
  1495.   return ( (MRESULT) IDM_KEYS_HELP ) ;
  1496. }
  1497.  
  1498. /****************************************************************************
  1499.  *                                                                          *
  1500.  *      Process Help Manager Error                                          *
  1501.  *                                                                          *
  1502.  ****************************************************************************/
  1503.  
  1504. STATIC MRESULT APIENTRY HelpError ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1505.  
  1506.  /***************************************************************************
  1507.   * Local Declarations                                                      *
  1508.   ***************************************************************************/
  1509.  
  1510.   static struct
  1511.   {
  1512.     ULONG Error ;
  1513.     USHORT StringId ;
  1514.   }
  1515.   HelpErrors [] =
  1516.   {
  1517.     { HMERR_NO_FRAME_WND_IN_CHAIN,     IDS_HMERR_NO_FRAME_WND_IN_CHAIN },
  1518.     { HMERR_INVALID_ASSOC_APP_WND,     IDS_HMERR_INVALID_ASSOC_APP_WND },
  1519.     { HMERR_INVALID_ASSOC_HELP_INST,   IDS_HMERR_INVALID_ASSOC_HELP_IN },
  1520.     { HMERR_INVALID_DESTROY_HELP_INST, IDS_HMERR_INVALID_DESTROY_HELP_ },
  1521.     { HMERR_NO_HELP_INST_IN_CHAIN,     IDS_HMERR_NO_HELP_INST_IN_CHAIN },
  1522.     { HMERR_INVALID_HELP_INSTANCE_HDL, IDS_HMERR_INVALID_HELP_INSTANCE },
  1523.     { HMERR_INVALID_QUERY_APP_WND,     IDS_HMERR_INVALID_QUERY_APP_WND },
  1524.     { HMERR_HELP_INST_CALLED_INVALID,  IDS_HMERR_HELP_INST_CALLED_INVA },
  1525.     { HMERR_HELPTABLE_UNDEFINE,        IDS_HMERR_HELPTABLE_UNDEFINE    },
  1526.     { HMERR_HELP_INSTANCE_UNDEFINE,    IDS_HMERR_HELP_INSTANCE_UNDEFIN },
  1527.     { HMERR_HELPITEM_NOT_FOUND,        IDS_HMERR_HELPITEM_NOT_FOUND    },
  1528.     { HMERR_INVALID_HELPSUBITEM_SIZE,  IDS_HMERR_INVALID_HELPSUBITEM_S },
  1529.     { HMERR_HELPSUBITEM_NOT_FOUND,     IDS_HMERR_HELPSUBITEM_NOT_FOUND },
  1530.     { HMERR_INDEX_NOT_FOUND,           IDS_HMERR_INDEX_NOT_FOUND       },
  1531.     { HMERR_CONTENT_NOT_FOUND,         IDS_HMERR_CONTENT_NOT_FOUND     },
  1532.     { HMERR_OPEN_LIB_FILE,             IDS_HMERR_OPEN_LIB_FILE         },
  1533.     { HMERR_READ_LIB_FILE,             IDS_HMERR_READ_LIB_FILE         },
  1534.     { HMERR_CLOSE_LIB_FILE,            IDS_HMERR_CLOSE_LIB_FILE        },
  1535.     { HMERR_INVALID_LIB_FILE,          IDS_HMERR_INVALID_LIB_FILE      },
  1536.     { HMERR_NO_MEMORY,                 IDS_HMERR_NO_MEMORY             },
  1537.     { HMERR_ALLOCATE_SEGMENT,          IDS_HMERR_ALLOCATE_SEGMENT      },
  1538.     { HMERR_FREE_MEMORY,               IDS_HMERR_FREE_MEMORY           },
  1539.     { HMERR_PANEL_NOT_FOUND,           IDS_HMERR_PANEL_NOT_FOUND       },
  1540.     { HMERR_DATABASE_NOT_OPEN,         IDS_HMERR_DATABASE_NOT_OPEN     },
  1541.     { 0,                               IDS_HMERR_UNKNOWN               }
  1542.   } ;
  1543.  
  1544.   ULONG ErrorCode = (ULONG) LONGFROMMP ( mp1 ) ;
  1545.  
  1546.  /***************************************************************************
  1547.   * Find the instance data.                                                 *
  1548.   ***************************************************************************/
  1549.  
  1550.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1551.  
  1552.  /***************************************************************************
  1553.   * Find the error code in the message table.                               *
  1554.   ***************************************************************************/
  1555.  
  1556.   int Index = 0 ;
  1557.   while ( HelpErrors[Index].Error
  1558.     AND ( HelpErrors[Index].Error != ErrorCode ) )
  1559.   {
  1560.     Index ++ ;
  1561.   }
  1562.  
  1563.  /***************************************************************************
  1564.   * Get the message texts.                                                  *
  1565.   ***************************************************************************/
  1566.  
  1567.   ResourceString Title ( Data->Library->QueryHandle(), IDS_HMERR ) ;
  1568.  
  1569.   ResourceString Message ( Data->Library->QueryHandle(), HelpErrors[Index].StringId ) ;
  1570.  
  1571.  /***************************************************************************
  1572.   * Display the error message.                                              *
  1573.   ***************************************************************************/
  1574.  
  1575.   WinMessageBox
  1576.   (
  1577.     HWND_DESKTOP,
  1578.     hwnd,
  1579.     PSZ(Message),
  1580.     PSZ(Title),
  1581.     0,
  1582.     MB_OK | MB_WARNING
  1583.   ) ;
  1584.  
  1585.  /***************************************************************************
  1586.   * Return zero, indicating that the message was processed.                 *
  1587.   ***************************************************************************/
  1588.  
  1589.   return ( MRFROMSHORT ( 0 ) ) ;
  1590. }
  1591.  
  1592. /****************************************************************************
  1593.  *                                                                          *
  1594.  *      Process "Extended Help Undefined" notification                      *
  1595.  *                                                                          *
  1596.  ****************************************************************************/
  1597.  
  1598. STATIC MRESULT APIENTRY ExtHelpUndefined ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1599.  
  1600.  /***************************************************************************
  1601.   * Find the instance data.                                                 *
  1602.   ***************************************************************************/
  1603.  
  1604.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1605.  
  1606.  /***************************************************************************
  1607.   * Get the message texts.                                                  *
  1608.   ***************************************************************************/
  1609.  
  1610.   ResourceString Title ( Data->Library->QueryHandle(), IDS_HMERR ) ;
  1611.  
  1612.   ResourceString Message ( Data->Library->QueryHandle(), IDS_HMERR_EXTHELPUNDEFINED ) ;
  1613.  
  1614.  /***************************************************************************
  1615.   * Display the error message.                                              *
  1616.   ***************************************************************************/
  1617.  
  1618.   WinMessageBox
  1619.   (
  1620.     HWND_DESKTOP,
  1621.     hwnd,
  1622.     PSZ(Message),
  1623.     PSZ(Title),
  1624.     0,
  1625.     MB_OK | MB_WARNING
  1626.   ) ;
  1627.  
  1628.  /***************************************************************************
  1629.   * Return zero, indicating that the message was processed.                 *
  1630.   ***************************************************************************/
  1631.  
  1632.   return ( MRFROMSHORT ( 0 ) ) ;
  1633. }
  1634.  
  1635. /****************************************************************************
  1636.  *                                                                          *
  1637.  *      Process "Help Subitem Not Found" notification                       *
  1638.  *                                                                          *
  1639.  ****************************************************************************/
  1640.  
  1641. STATIC MRESULT APIENTRY HelpSubitemNotFound ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1642.  
  1643.  /***************************************************************************
  1644.   * Find the instance data.                                                 *
  1645.   ***************************************************************************/
  1646.  
  1647.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1648.  
  1649.  /***************************************************************************
  1650.   * Get the title text.                                                     *
  1651.   ***************************************************************************/
  1652.  
  1653.   ResourceString Title ( Data->Library->QueryHandle(), IDS_HMERR ) ;
  1654.  
  1655.  /***************************************************************************
  1656.   * Format the error message.                                               *
  1657.   ***************************************************************************/
  1658.  
  1659.   USHORT Topic = (USHORT) SHORT1FROMMP ( mp2 ) ;
  1660.   USHORT Subtopic = (USHORT) SHORT2FROMMP ( mp2 ) ;
  1661.  
  1662.   ResourceString Frame   ( Data->Library->QueryHandle(), IDS_HELPMODE_FRAME ) ;
  1663.   ResourceString Menu    ( Data->Library->QueryHandle(), IDS_HELPMODE_MENU ) ;
  1664.   ResourceString Window  ( Data->Library->QueryHandle(), IDS_HELPMODE_WINDOW ) ;
  1665.   ResourceString Unknown ( Data->Library->QueryHandle(), IDS_HELPMODE_UNKNOWN ) ;
  1666.  
  1667.   PBYTE Mode ;
  1668.   switch ( SHORT1FROMMP ( mp1 ) )
  1669.   {
  1670.     case HLPM_FRAME:
  1671.       Mode = PSZ(Frame) ;
  1672.       break ;
  1673.  
  1674.     case HLPM_MENU:
  1675.       Mode = PSZ(Menu) ;
  1676.       break ;
  1677.  
  1678.     case HLPM_WINDOW:
  1679.       Mode = PSZ(Window) ;
  1680.       break ;
  1681.  
  1682.     default:
  1683.       Mode = PSZ(Unknown) ;
  1684.   }
  1685.  
  1686.   ResourceString Format ( Data->Library->QueryHandle(), IDS_HELPSUBITEMNOTFOUND ) ;
  1687.  
  1688.   BYTE Message [200] ;
  1689.   sprintf ( PCHAR(Message), PCHAR(Format), Mode, Topic, Subtopic ) ;
  1690.  
  1691.  /***************************************************************************
  1692.   * Display the error message.                                              *
  1693.   ***************************************************************************/
  1694.  
  1695.   WinMessageBox
  1696.   (
  1697.     HWND_DESKTOP,
  1698.     hwnd,
  1699.     Message,
  1700.     PSZ(Title),
  1701.     0,
  1702.     MB_OK | MB_WARNING
  1703.   ) ;
  1704.  
  1705.  /***************************************************************************
  1706.   * Return zero, indicating that the message was processed.                 *
  1707.   ***************************************************************************/
  1708.  
  1709.   return ( MRFROMSHORT ( 0 ) ) ;
  1710. }
  1711.  
  1712. /****************************************************************************
  1713.  *                                                                          *
  1714.  *      Process Refresh message.                                            *
  1715.  *                                                                          *
  1716.  ****************************************************************************/
  1717.  
  1718. STATIC MRESULT APIENTRY Refresh ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) {
  1719.  
  1720.  /***************************************************************************
  1721.   * Find the instance data.                                                 *
  1722.   ***************************************************************************/
  1723.  
  1724.   PDATA Data = PDATA ( WinQueryWindowPtr ( hwnd, QWL_USER ) ) ;
  1725.  
  1726.  /***************************************************************************
  1727.   * If we're supposed to float the window, do so here.                      *
  1728.   ***************************************************************************/
  1729.  
  1730.   if ( Data->IniData.Float )
  1731.     WinSetWindowPos ( WinQueryWindow(hwnd,QW_PARENT), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER ) ;
  1732.  
  1733.  /***************************************************************************
  1734.   * Save the idle counter.                                                  *
  1735.   ***************************************************************************/
  1736.  
  1737.   Data->IniData.IdleCount = LONGFROMMP ( mp1 ) ;
  1738.  
  1739.  /***************************************************************************
  1740.   * Determine if drive mask has changed.                                    *
  1741.   ***************************************************************************/
  1742.  
  1743.   ULONG Drive ;
  1744.   ULONG Drives ;
  1745.   DosQueryCurrentDisk ( &Drive, &Drives ) ;
  1746.  
  1747.   if ( Drives != Data->Drives ) {
  1748.  
  1749.    /*************************************************************************
  1750.     * It has.  First save the display options.                              *
  1751.     *************************************************************************/
  1752.  
  1753.     SaveApplication ( hwnd, WM_SAVEAPPLICATION, 0, 0 ) ;
  1754.  
  1755.    /*************************************************************************
  1756.     * Next, update the drive item list.                                     *
  1757.     *************************************************************************/
  1758.  
  1759.     UpdateDriveList ( Data->Proc->QueryAnchor(), Data->Library->QueryHandle(), Data->IniFile->QueryHandle(), 
  1760.       &Data->IniData, Data->Drives, Drives ) ;
  1761.  
  1762.    /*************************************************************************
  1763.     * If the controls are hidden, hide the whole window and reveal the      *
  1764.     *   controls.  Otherwise the menu wouldn't get updated correctly.       *
  1765.     *************************************************************************/
  1766.  
  1767.     if ( Data->IniData.HideControls ) {
  1768.       WinShowWindow ( WinQueryWindow(hwnd,QW_PARENT), FALSE ) ;
  1769.       HideControls
  1770.       (
  1771.         FALSE,
  1772.         WinQueryWindow ( hwnd, QW_PARENT ),
  1773.         Data->hwndSysMenu,
  1774.         Data->hwndTitleBar,
  1775.         Data->hwndMinMax
  1776.       ) ;
  1777.     }
  1778.  
  1779.    /*************************************************************************
  1780.     * If the controls were supposed to be hidden, hide them once more and   *
  1781.     *   show the window to the world again.                                 *
  1782.     *************************************************************************/
  1783.  
  1784.     if ( Data->IniData.HideControls ) {
  1785.       HideControls
  1786.       (
  1787.         TRUE,
  1788.         WinQueryWindow ( hwnd, QW_PARENT ),
  1789.         Data->hwndSysMenu,
  1790.         Data->hwndTitleBar,
  1791.         Data->hwndMinMax
  1792.       ) ;
  1793.       WinShowWindow ( WinQueryWindow(hwnd,QW_PARENT), TRUE ) ;
  1794.     }
  1795.  
  1796.    /*************************************************************************
  1797.     * Save the updated drive mask.                                          *
  1798.     *************************************************************************/
  1799.  
  1800.     Data->Drives = Drives ;
  1801.  
  1802.    /*************************************************************************
  1803.     * Resize the window to accommodate the new option list.                 *
  1804.     *************************************************************************/
  1805.  
  1806.     ResizeWindow ( hwnd, &Data->IniData ) ;
  1807.   }
  1808.  
  1809.  /***************************************************************************
  1810.   * Update the statistics.                                                  *
  1811.   ***************************************************************************/
  1812.  
  1813.   UpdateWindow ( hwnd, Data, FALSE ) ;
  1814.  
  1815.  /***************************************************************************
  1816.   * Return zero, indicating that the message was processed.                 *
  1817.   ***************************************************************************/
  1818.  
  1819.   return ( MRFROMSHORT ( 0 ) ) ;
  1820. }
  1821.  
  1822.  
  1823. /****************************************************************************
  1824.  *                                                                          *
  1825.  *                           Get IniData Data                               *
  1826.  *                                                                          *
  1827.  ****************************************************************************/
  1828.  
  1829. STATIC int GetIniData ( HAB Anchor, HMODULE Library, HINI IniHandle, PINIDATA IniData ) {
  1830.  
  1831.  /***************************************************************************
  1832.   * Get the window's current size and position.                             *
  1833.   ***************************************************************************/
  1834.  
  1835.   #pragma pack(2)
  1836.   typedef struct {
  1837.     USHORT Filler ;
  1838.     USHORT fs ;
  1839.     USHORT cy, cx, y, x ;
  1840.     HWND hwndInsertBehind ;
  1841.     HWND hwnd ;
  1842.   } OLDSWP ;
  1843.   #pragma pack()
  1844.  
  1845.   ULONG Size ;
  1846.   memset ( &IniData->Position, 0, sizeof(IniData->Position) ) ;
  1847.   IniData->fPosition = FALSE ;
  1848.   if ( PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("Position"), &Size ) )
  1849.   {
  1850.     if ( Size == sizeof(OLDSWP)-sizeof(USHORT) )
  1851.     {
  1852.       OLDSWP OldPosition ;
  1853.       if ( PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("Position"), &OldPosition.fs, &Size ) )
  1854.       {
  1855.         IniData->Position.fl = OldPosition.fs ;
  1856.         IniData->Position.cy = OldPosition.cy ;
  1857.         IniData->Position.cx = OldPosition.cx ;
  1858.         IniData->Position.y = OldPosition.y ;
  1859.         IniData->Position.x = OldPosition.x ;
  1860.         IniData->Position.hwndInsertBehind = OldPosition.hwndInsertBehind ;
  1861.         IniData->Position.hwnd = OldPosition.hwnd ;
  1862.         IniData->fPosition = TRUE ;
  1863.       }
  1864.     }
  1865.     else if ( Size == sizeof(IniData->Position) )
  1866.     {
  1867.       if ( PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("Position"), &IniData->Position, &Size ) )
  1868.       {
  1869.         IniData->fPosition = TRUE ;
  1870.       }
  1871.     }
  1872.   }
  1873.  
  1874.   if ( NOT IniData->fPosition )
  1875.   {
  1876.     if ( IniHandle == HINI_USERPROFILE )
  1877.     {
  1878.       return ( 1 ) ;
  1879.     }
  1880.   }
  1881.  
  1882.  /***************************************************************************
  1883.   * Get the program options.                                                *
  1884.   ***************************************************************************/
  1885.  
  1886.   IniData->HideControls = FALSE ;
  1887.   IniData->fHideControls = FALSE ;
  1888.   if 
  1889.   ( 
  1890.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("HideControls"), &Size )
  1891.     AND
  1892.     ( ( Size == sizeof(IniData->HideControls) ) OR ( Size == sizeof(short) ) )
  1893.     AND
  1894.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("HideControls"), &IniData->HideControls, &Size )
  1895.   )
  1896.   {
  1897.     IniData->fHideControls = TRUE ;
  1898.   }
  1899.  
  1900.   IniData->Float = FALSE ;
  1901.   IniData->fFloat = FALSE ;
  1902.   if 
  1903.   ( 
  1904.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("Float"), &Size )
  1905.     AND
  1906.     ( Size == sizeof(IniData->Float) ) 
  1907.     AND
  1908.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("Float"), &IniData->Float, &Size )
  1909.   )
  1910.   {
  1911.     IniData->fFloat = TRUE ;
  1912.   }
  1913.  
  1914.   IniData->Animate = FALSE ;
  1915.   IniData->fAnimate = FALSE ;
  1916.   if
  1917.   (
  1918.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("Animate"), &Size )
  1919.     AND
  1920.     ( Size == sizeof(IniData->Animate) ) 
  1921.     AND
  1922.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("Animate"), &IniData->Animate, &Size )
  1923.   )
  1924.   {
  1925.     IniData->fAnimate = TRUE ;
  1926.   }
  1927.  
  1928.   IniData->ShowFileSystemNames = TRUE ;
  1929.   IniData->fShowFileSystemNames = FALSE ;
  1930.   if
  1931.   (
  1932.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("ShowFileSystemNames"), &Size )
  1933.     AND
  1934.     ( Size == sizeof(IniData->ShowFileSystemNames) )
  1935.     AND
  1936.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("ShowFileSystemNames"), &IniData->ShowFileSystemNames, &Size )
  1937.   )
  1938.   {
  1939.     IniData->fShowFileSystemNames = TRUE ;
  1940.   }
  1941.  
  1942.   IniData->ShowDiskLabels = TRUE ;
  1943.   IniData->fShowDiskLabels = FALSE ;
  1944.   if
  1945.   (
  1946.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("ShowDiskLabels"), &Size )
  1947.     AND
  1948.     ( Size == sizeof(IniData->ShowDiskLabels) )
  1949.     AND
  1950.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("ShowDiskLabels"), &IniData->ShowDiskLabels, &Size )
  1951.   )
  1952.   {
  1953.     IniData->fShowDiskLabels = TRUE ;
  1954.   }
  1955.  
  1956.   IniData->MonitorPriority = PRTYD_MAXIMUM ;
  1957.   IniData->fMonitorPriority = FALSE ;
  1958.   if
  1959.   (
  1960.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("MonitorPriority"), &Size )
  1961.     AND
  1962.     ( Size == sizeof(IniData->MonitorPriority) )
  1963.     AND
  1964.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("MonitorPriority"), &IniData->MonitorPriority, &Size )
  1965.   )
  1966.   {
  1967.     IniData->fMonitorPriority = TRUE ;
  1968.   }
  1969.  
  1970.   IniData->TimerInterval = 1000 ;
  1971.   IniData->fTimerInterval = FALSE ;
  1972.   if 
  1973.   ( 
  1974.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("TimerInterval"), &Size )
  1975.     AND
  1976.     ( ( Size == sizeof(IniData->TimerInterval) ) OR ( Size == sizeof(short) ) )
  1977.     AND
  1978.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("TimerInterval"), &IniData->TimerInterval, &Size ) 
  1979.   )
  1980.   {
  1981.     IniData->fTimerInterval = TRUE ;
  1982.   }
  1983.  
  1984.  /***************************************************************************
  1985.   * Get the presentation parameters.                                        *
  1986.   ***************************************************************************/
  1987.  
  1988.   strcpy ( PCHAR(IniData->FontNameSize), "" ) ;
  1989.   IniData->fFontNameSize = FALSE ;
  1990.   if
  1991.   (
  1992.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("FontNameSize"), &Size )
  1993.     AND
  1994.     ( Size == sizeof(IniData->FontNameSize) )
  1995.     AND
  1996.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("FontNameSize"), &IniData->FontNameSize, &Size )
  1997.   )
  1998.   {
  1999.     IniData->fFontNameSize = TRUE ;
  2000.   }
  2001.  
  2002.   IniData->BackColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_WINDOW, 0L ) ;
  2003.   IniData->fBackColor = FALSE ;
  2004.   if
  2005.   (
  2006.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("BackgroundColor"), &Size )
  2007.     AND
  2008.     ( Size == sizeof(IniData->BackColor) )
  2009.     AND
  2010.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("BackgroundColor"), &IniData->BackColor, &Size )
  2011.   )
  2012.   {
  2013.     IniData->fBackColor = TRUE ;
  2014.   }
  2015.  
  2016.   IniData->TextColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0L ) ;
  2017.   IniData->fTextColor = FALSE ;
  2018.   if
  2019.   (
  2020.     PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ("ForegroundColor"), &Size )
  2021.     AND
  2022.     ( Size == sizeof(IniData->TextColor) )
  2023.     AND
  2024.     PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ("ForegroundColor"), &IniData->TextColor, &Size )
  2025.   )
  2026.   {
  2027.     IniData->fTextColor = TRUE ;
  2028.   }
  2029.  
  2030.  /***************************************************************************
  2031.   * Initialize the global resource strings.                                 *
  2032.   ***************************************************************************/
  2033.  
  2034.   IniData->Day        = new ResourceString ( Library, IDS_DAY ) ;
  2035.   IniData->Days       = new ResourceString ( Library, IDS_DAYS ) ;
  2036.   IniData->DaysOfWeek = new ResourceString ( Library, IDS_DAYSOFWEEK ) ;
  2037.   IniData->DriveError = new ResourceString ( Library, IDS_DRIVEERROR ) ;
  2038.  
  2039.  /***************************************************************************
  2040.   * Get country information.                                                *
  2041.   ***************************************************************************/
  2042.  
  2043.   COUNTRYCODE CountryCode ;
  2044.   ULONG Count ;
  2045.   ULONG Status ;
  2046.  
  2047.   CountryCode.country = 0 ;
  2048.   CountryCode.codepage = 0 ;
  2049.  
  2050.   Status = DosGetCtryInfo ( sizeof(IniData->CountryInfo), &CountryCode,
  2051.     &IniData->CountryInfo, &Count ) ;
  2052.   if ( Status )
  2053.   {
  2054.     IniData->CountryInfo.fsDateFmt = DATEFMT_MM_DD_YY ;
  2055.     IniData->CountryInfo.fsTimeFmt = 0 ;
  2056.     IniData->CountryInfo.szDateSeparator[0] = '/' ;
  2057.     IniData->CountryInfo.szDateSeparator[1] = 0 ;
  2058.     IniData->CountryInfo.szTimeSeparator[0] = ':' ;
  2059.     IniData->CountryInfo.szTimeSeparator[1] = 0 ;
  2060.     IniData->CountryInfo.szThousandsSeparator[0] = ',' ;
  2061.     IniData->CountryInfo.szThousandsSeparator[1] = 0 ;
  2062.   }
  2063.  
  2064.   char Text [2] ;
  2065.   Size = 2 ;
  2066.   if ( PrfQueryProfileData ( HINI_USERPROFILE, PSZ("PM_National"), PSZ("iDate"), Text, &Size ) ) {
  2067.      IniData->CountryInfo.fsDateFmt = atoi ( Text ) ;
  2068.   } /* endif */
  2069.  
  2070.   Size = 2 ;
  2071.   if ( PrfQueryProfileData ( HINI_USERPROFILE, PSZ("PM_National"), PSZ("iTime"), Text, &Size ) ) {
  2072.      IniData->CountryInfo.fsTimeFmt = atoi ( Text ) ;
  2073.   } /* endif */
  2074.  
  2075.   Size = 2 ;
  2076.   PrfQueryProfileData ( HINI_USERPROFILE, PSZ("PM_National"), PSZ("sDate"), IniData->CountryInfo.szDateSeparator, &Size ) ;
  2077.  
  2078.   Size = 2 ;
  2079.   PrfQueryProfileData ( HINI_USERPROFILE, PSZ("PM_National"), PSZ("sTime"), IniData->CountryInfo.szTimeSeparator, &Size ) ;
  2080.  
  2081.   Size = 3 ;
  2082.   strcpy ( IniData->szAm, "am" ) ;
  2083.   PrfQueryProfileData ( HINI_USERPROFILE, PSZ("PM_National"), PSZ("s1159"), IniData->szAm, &Size ) ;
  2084.  
  2085.   Size = 3 ;
  2086.   strcpy ( IniData->szPm, "pm" ) ;
  2087.   PrfQueryProfileData ( HINI_USERPROFILE, PSZ("PM_National"), PSZ("s2359"), IniData->szPm, &Size ) ;
  2088.  
  2089.   Size = 2 ;
  2090.   PrfQueryProfileData ( HINI_USERPROFILE, PSZ("PM_National"), PSZ("sThousand"), IniData->CountryInfo.szThousandsSeparator, &Size ) ;
  2091.  
  2092.  /***************************************************************************
  2093.   * Get the SWAPPATH statement from CONFIG.SYS.                             *
  2094.   ***************************************************************************/
  2095.  
  2096.   PSZ Swappath = ScanSystemConfig ( Anchor, PSZ("SWAPPATH") ) ;
  2097.  
  2098.   if ( Swappath == NULL ) {
  2099.     Swappath = PSZ("C:\\OS2\\SYSTEM 0") ;
  2100.   }
  2101.  
  2102.   sscanf ( PCHAR(Swappath), "%s %li",
  2103.     IniData->SwapPath, &IniData->MinFree ) ;
  2104.  
  2105.  /***************************************************************************
  2106.   * Find out where the spool work directory is.                             *
  2107.   ***************************************************************************/
  2108.  
  2109.   IniData->SpoolPath = 0 ;
  2110.  
  2111.   if ( PrfQueryProfileSize ( HINI_PROFILE, PSZ("PM_SPOOLER"), PSZ("DIR"), &Size ) )
  2112.   {
  2113.     IniData->SpoolPath = PSZ ( malloc ( (int)Size ) ) ;
  2114.  
  2115.     if ( IniData->SpoolPath )
  2116.     {
  2117.       if ( PrfQueryProfileData ( HINI_PROFILE, PSZ("PM_SPOOLER"), PSZ("DIR"), IniData->SpoolPath, &Size ) )
  2118.       {
  2119.         PBYTE p = PBYTE( strchr ( PCHAR(IniData->SpoolPath), ';' ) ) ;
  2120.         if ( p )
  2121.         {
  2122.           *p = 0 ;
  2123.         }
  2124.       }
  2125.       else
  2126.       {
  2127.         free ( IniData->SpoolPath ) ;
  2128.         IniData->SpoolPath = 0 ;
  2129.       }
  2130.     }
  2131.   }
  2132.  
  2133.   if ( IniData->SpoolPath == 0 )
  2134.      IniData->SpoolPath = PSZ ( "C:\\SPOOL" ) ;
  2135.  
  2136.  /***************************************************************************
  2137.   * Build the fixed portion of the item list.                               *
  2138.   ***************************************************************************/
  2139.  
  2140.   ResourceString ClockLabel ( Library, IDS_SHOW_CLOCK_LABEL ) ;
  2141.   ResourceString ClockOption ( Library, IDS_SHOW_CLOCK_OPTION ) ;
  2142.   IniData->Items[ITEM_CLOCK] = new Clock ( ITEM_CLOCK,
  2143.     PSZ("ShowClock"), PSZ(ClockLabel), PSZ(ClockOption),
  2144.     IniData->CountryInfo, IniData->szAm, IniData->szPm, IniData->DaysOfWeek ) ;
  2145.  
  2146.   ResourceString ElapsedLabel ( Library, IDS_SHOW_ELAPSED_LABEL ) ;
  2147.   ResourceString ElapsedOption ( Library, IDS_SHOW_ELAPSED_OPTION ) ;
  2148.   IniData->Items[ITEM_ELAPSEDTIME] = new ElapsedTime ( ITEM_ELAPSEDTIME,
  2149.     PSZ("ShowElapsed"), PSZ(ElapsedLabel), PSZ(ElapsedOption),
  2150.     IniData->CountryInfo,
  2151.     IniData->Day,
  2152.     IniData->Days ) ;
  2153.  
  2154.   ResourceString SwapSizeLabel ( Library, IDS_SHOW_SWAPSIZE_LABEL ) ;
  2155.   ResourceString SwapSizeOption ( Library, IDS_SHOW_SWAPSIZE_OPTION ) ;
  2156.   IniData->Items[ITEM_SWAPFILESIZE] = new SwapSize ( ITEM_SWAPFILESIZE,
  2157.     PSZ("ShowSwapsize"), PSZ(SwapSizeLabel), PSZ(SwapSizeOption),
  2158.     IniData->CountryInfo,
  2159.     IniData->SwapPath ) ;
  2160.  
  2161.   ResourceString SwapFreeLabel ( Library, IDS_SHOW_SWAPFREE_LABEL ) ;
  2162.   ResourceString SwapFreeOption ( Library, IDS_SHOW_SWAPFREE_OPTION ) ;
  2163.   IniData->Items[ITEM_SWAPDISKFREE] = new SwapFree ( ITEM_SWAPDISKFREE,
  2164.     PSZ("ShowSwapfree"), PSZ(SwapFreeLabel), PSZ(SwapFreeOption),
  2165.     IniData->CountryInfo,
  2166.     IniData->SwapPath,
  2167.     IniData->MinFree ) ;
  2168.  
  2169.   ResourceString MemoryLabel ( Library, IDS_SHOW_MEMORY_LABEL ) ;
  2170.   ResourceString MemoryOption ( Library, IDS_SHOW_MEMORY_OPTION ) ;
  2171.   IniData->Items[ITEM_MEMORYFREE] = new MemoryFree ( ITEM_MEMORYFREE,
  2172.     PSZ("ShowMemory"), PSZ(MemoryLabel), PSZ(MemoryOption),
  2173.     IniData->CountryInfo ) ;
  2174.  
  2175.   ResourceString VirtualLabel ( Library, IDS_SHOW_VIRTUAL_LABEL ) ;
  2176.   ResourceString VirtualOption ( Library, IDS_SHOW_VIRTUAL_OPTION ) ;
  2177.   IniData->Items[ITEM_VIRTUALFREE] = new VirtualFree ( ITEM_VIRTUALFREE,
  2178.     PSZ("ShowVirtual"), PSZ(VirtualLabel), PSZ(VirtualOption),
  2179.     IniData->CountryInfo ) ;
  2180.  
  2181.   ResourceString SpoolSizeLabel ( Library, IDS_SHOW_SPOOLSIZE_LABEL ) ;
  2182.   ResourceString SpoolSizeOption ( Library, IDS_SHOW_SPOOLSIZE_OPTION ) ;
  2183.   IniData->Items[ITEM_SPOOLFILESIZE] = new SpoolSize ( ITEM_SPOOLFILESIZE,
  2184.     PSZ("ShowSpoolSize"), PSZ(SpoolSizeLabel), PSZ(SpoolSizeOption),
  2185.     IniData->CountryInfo,
  2186.     IniData->SpoolPath ) ;
  2187.  
  2188.   ResourceString CpuLoadLabel ( Library, IDS_SHOW_CPULOAD_LABEL ) ;
  2189.   ResourceString CpuLoadOption ( Library, IDS_SHOW_CPULOAD_OPTION ) ;
  2190.   IniData->Items[ITEM_CPULOAD] = new CpuLoad ( ITEM_CPULOAD,
  2191.     PSZ("ShowCpuLoad"), PSZ(CpuLoadLabel), PSZ(CpuLoadOption),
  2192.     IniData->MaxCount,
  2193.     &IniData->IdleCount ) ;
  2194.  
  2195.   ResourceString TaskCountLabel ( Library, IDS_SHOW_TASKCOUNT_LABEL ) ;
  2196.   ResourceString TaskCountOption ( Library, IDS_SHOW_TASKCOUNT_OPTION ) ;
  2197.   IniData->Items[ITEM_TASKCOUNT] = new TaskCount ( ITEM_TASKCOUNT,
  2198.     PSZ("ShowTaskCount"), PSZ(TaskCountLabel), PSZ(TaskCountOption),
  2199.     Anchor ) ;
  2200.  
  2201.   ResourceString TotalFreeLabel ( Library, IDS_SHOW_TOTALFREE_LABEL ) ;
  2202.   ResourceString TotalFreeOption ( Library, IDS_SHOW_TOTALFREE_OPTION ) ;
  2203.   IniData->Items[ITEM_TOTALFREE] = new TotalFree ( ITEM_TOTALFREE,
  2204.     PSZ("ShowTotalFree"), PSZ(TotalFreeLabel), PSZ(TotalFreeOption),
  2205.     IniData->CountryInfo, 0 ) ;
  2206.  
  2207.   for ( int i=0; i<ITEM_BASE_COUNT; i++ )
  2208.   {
  2209.     BOOL Flag = TRUE ;
  2210.     if 
  2211.     ( 
  2212.       PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), IniData->Items[i]->QueryName(), &Size )
  2213.       AND
  2214.       ( ( Size == sizeof(Flag) ) OR ( Size == sizeof(short) ) )
  2215.       AND 
  2216.       PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), IniData->Items[i]->QueryName(), &Flag, &Size )
  2217.     )
  2218.     {
  2219.       ;
  2220.     }
  2221.  
  2222.     if ( Flag )
  2223.       IniData->Items[i]->SetFlag() ;
  2224.     else
  2225.       IniData->Items[i]->ResetFlag() ;
  2226.   }
  2227.  
  2228.  /***************************************************************************
  2229.   * Add items for each drive on the system.                                 *
  2230.   ***************************************************************************/
  2231.  
  2232.   ULONG Drive, Drives ;
  2233.   DosQueryCurrentDisk ( &Drive, &Drives ) ;
  2234.   UpdateDriveList ( Anchor, Library, IniHandle, IniData, 0, Drives ) ;
  2235.  
  2236.   return ( 0 ) ;
  2237. }
  2238.  
  2239. /****************************************************************************
  2240.  *                                                                          *
  2241.  *                           Put IniData Data                               *
  2242.  *                                                                          *
  2243.  ****************************************************************************/
  2244.  
  2245. STATIC void PutIniData ( HINI IniHandle, PINIDATA IniData )
  2246. {
  2247.  /***************************************************************************
  2248.   * Save the window's current size and position.                            *
  2249.   ***************************************************************************/
  2250.  
  2251.   PrfWriteProfileData
  2252.   (
  2253.     IniHandle,
  2254.     PSZ(PROGRAM_NAME),
  2255.     PSZ("Position"),
  2256.     &IniData->Position,
  2257.     sizeof(IniData->Position)
  2258.   ) ;
  2259.  
  2260.  /***************************************************************************
  2261.   * Save the program options.                                               *
  2262.   ***************************************************************************/
  2263.  
  2264.   if ( IniData->fHideControls )
  2265.   {
  2266.     PrfWriteProfileData
  2267.     (
  2268.       IniHandle,
  2269.       PSZ(PROGRAM_NAME),
  2270.       PSZ("HideControls"),
  2271.       &IniData->HideControls,
  2272.       sizeof(IniData->HideControls)
  2273.     ) ;
  2274.   }
  2275.  
  2276.   if ( IniData->fFloat )
  2277.   {
  2278.     PrfWriteProfileData
  2279.     (
  2280.       IniHandle,
  2281.       PSZ(PROGRAM_NAME),
  2282.       PSZ("Float"),
  2283.       &IniData->Float,
  2284.       sizeof(IniData->Float)
  2285.     ) ;
  2286.   }
  2287.  
  2288.   if ( IniData->fAnimate )
  2289.   {
  2290.     PrfWriteProfileData
  2291.     (
  2292.       IniHandle,
  2293.       PSZ(PROGRAM_NAME),
  2294.       PSZ("Animate"),
  2295.       &IniData->Animate,
  2296.       sizeof(IniData->Animate)
  2297.     ) ;
  2298.   }
  2299.  
  2300.   if ( IniData->fShowFileSystemNames )
  2301.   {
  2302.     PrfWriteProfileData
  2303.     (
  2304.       IniHandle,
  2305.       PSZ(PROGRAM_NAME),
  2306.       PSZ("ShowFileSystemNames"),
  2307.       &IniData->ShowFileSystemNames,
  2308.       sizeof(IniData->ShowFileSystemNames)
  2309.     ) ;
  2310.   }
  2311.  
  2312.   if ( IniData->fShowDiskLabels )
  2313.   {
  2314.     PrfWriteProfileData
  2315.     (
  2316.       IniHandle,
  2317.       PSZ(PROGRAM_NAME),
  2318.       PSZ("ShowDiskLabels"),
  2319.       &IniData->ShowDiskLabels,
  2320.       sizeof(IniData->ShowDiskLabels)
  2321.     ) ;
  2322.   }
  2323.  
  2324.   if ( IniData->fMonitorPriority )
  2325.   {
  2326.     PrfWriteProfileData
  2327.     (
  2328.       IniHandle,
  2329.       PSZ(PROGRAM_NAME),
  2330.       PSZ("MonitorPriority"),
  2331.       &IniData->MonitorPriority,
  2332.       sizeof(IniData->MonitorPriority)
  2333.     ) ;
  2334.   }
  2335.  
  2336.   if ( IniData->fTimerInterval )
  2337.   {
  2338.     PrfWriteProfileData
  2339.     (
  2340.       IniHandle,
  2341.       PSZ(PROGRAM_NAME),
  2342.       PSZ("TimerInterval"),
  2343.       &IniData->TimerInterval,
  2344.       sizeof(IniData->TimerInterval)
  2345.     ) ;
  2346.   }
  2347.  
  2348.  /***************************************************************************
  2349.   * Save the item options.                                                  *
  2350.   ***************************************************************************/
  2351.  
  2352.   for ( int i=0; i<IniData->ItemCount; i++ )
  2353.   {
  2354.     Item *pItem = IniData->Items [i] ;
  2355.     BOOL Flag = pItem->QueryFlag() ;
  2356.  
  2357.     PrfWriteProfileData
  2358.     (
  2359.       IniHandle,
  2360.       PSZ(PROGRAM_NAME),
  2361.       pItem->QueryName(),
  2362.       &Flag,
  2363.       sizeof(Flag)
  2364.     ) ;
  2365.   }
  2366.  
  2367.  /***************************************************************************
  2368.   * Save the presentation parameters.                                       *
  2369.   ***************************************************************************/
  2370.  
  2371.   if ( IniData->fFontNameSize )
  2372.   {
  2373.     PrfWriteProfileData
  2374.     (
  2375.       IniHandle,
  2376.       PSZ(PROGRAM_NAME),
  2377.       PSZ("FontNameSize"),
  2378.       IniData->FontNameSize,
  2379.       sizeof(IniData->FontNameSize)
  2380.     ) ;
  2381.   }
  2382.  
  2383.   if ( IniData->fBackColor )
  2384.   {
  2385.     PrfWriteProfileData
  2386.     (
  2387.       IniHandle,
  2388.       PSZ(PROGRAM_NAME),
  2389.       PSZ("BackgroundColor"),
  2390.       &IniData->BackColor,
  2391.       sizeof(IniData->BackColor)
  2392.     ) ;
  2393.   }
  2394.  
  2395.   if ( IniData->fTextColor )
  2396.   {
  2397.     PrfWriteProfileData
  2398.     (
  2399.       IniHandle,
  2400.       PSZ(PROGRAM_NAME),
  2401.       PSZ("ForegroundColor"),
  2402.       &IniData->TextColor,
  2403.       sizeof(IniData->TextColor)
  2404.     ) ;
  2405.   }
  2406. }
  2407.  
  2408. /****************************************************************************
  2409.  *                                                                          *
  2410.  *      Scan CONFIG.SYS for a keyword.  Return the value.                   *
  2411.  *                                                                          *
  2412.  ****************************************************************************/
  2413.  
  2414. STATIC PSZ ScanSystemConfig ( HAB Anchor, PSZ Keyword )
  2415. {
  2416.  /***************************************************************************
  2417.   * Get the boot drive number from the global information segment.          *
  2418.   ***************************************************************************/
  2419.  
  2420.   ULONG BootDrive ;
  2421.   DosQuerySysInfo ( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &BootDrive, sizeof(BootDrive) ) ;
  2422.  
  2423.  /***************************************************************************
  2424.   * Convert the keyword to upper case.                                      *
  2425.   ***************************************************************************/
  2426.  
  2427.   WinUpper ( Anchor, 0, 0, Keyword ) ;
  2428.  
  2429.  /***************************************************************************
  2430.   * Build the CONFIG.SYS path.                                              *
  2431.   ***************************************************************************/
  2432.  
  2433.   char Path [_MAX_PATH] ;
  2434.   Path[0] = (char) ( BootDrive + 'A' - 1 ) ;
  2435.   Path[1] = 0 ;
  2436.   strcat ( Path, ":\\CONFIG.SYS" ) ;
  2437.  
  2438.  /***************************************************************************
  2439.   * Open CONFIG.SYS for reading.                                            *
  2440.   ***************************************************************************/
  2441.  
  2442.   FILE *File = fopen ( Path, "r" ) ;
  2443.   if ( NOT File )
  2444.   {
  2445.     return ( 0 ) ;
  2446.   }
  2447.  
  2448.  /***************************************************************************
  2449.   * While there're more lines in CONFIG.SYS, read a line and check it.      *
  2450.   ***************************************************************************/
  2451.  
  2452.   static char Buffer [500] ;
  2453.   while ( fgets ( Buffer, sizeof(Buffer), File ) )
  2454.   {
  2455.  
  2456.    /*************************************************************************
  2457.     * Clean any trailing newline character from the input string.           *
  2458.     *************************************************************************/
  2459.  
  2460.     if ( Buffer[strlen(Buffer)-1] == '\n' )
  2461.     {
  2462.       Buffer[strlen(Buffer)-1] = 0 ;
  2463.     }
  2464.  
  2465.    /*************************************************************************
  2466.     * If keyword starts the line, we've found the line we want.  Close      *
  2467.     *   the file and return a pointer to the parameter text.                *
  2468.     *************************************************************************/
  2469.  
  2470.     WinUpper ( Anchor, 0, 0, PSZ(Buffer) ) ;
  2471.  
  2472.     if ( NOT strncmp ( Buffer, PCHAR(Keyword), strlen(PCHAR(Keyword)) )
  2473.       AND ( Buffer[strlen(PCHAR(Keyword))] == '=' ) )
  2474.     {
  2475.       fclose ( File ) ;
  2476.       return ( PSZ( Buffer + strlen(PCHAR(Keyword)) + 1 ) ) ;
  2477.     }
  2478.   }
  2479.  
  2480.  /***************************************************************************
  2481.   * Close the file.  We haven't found the line we wanted.                   *
  2482.   ***************************************************************************/
  2483.  
  2484.   fclose ( File ) ;
  2485.  
  2486.   return ( 0 ) ;
  2487. }
  2488.  
  2489. /****************************************************************************
  2490.  *                                                                          *
  2491.  *                       Resize Client Window                               *
  2492.  *                                                                          *
  2493.  ****************************************************************************/
  2494.  
  2495. STATIC void ResizeWindow ( HWND hwnd, PINIDATA IniData )
  2496. {
  2497.  /***************************************************************************
  2498.   * If the window is visible and minimized, restore it invisibly.           *
  2499.   ***************************************************************************/
  2500.  
  2501.   HWND hwndFrame = WinQueryWindow ( hwnd, QW_PARENT ) ;
  2502.  
  2503.   SHORT fHadToHide = FALSE ;
  2504.   SHORT fHadToRestore = FALSE ;
  2505.   if ( IniData->Position.fl & SWP_MINIMIZE )
  2506.   {
  2507.     if ( WinIsWindowVisible ( hwndFrame ) )
  2508.     {
  2509.       WinShowWindow ( hwndFrame, FALSE ) ;
  2510.       fHadToHide = TRUE ;
  2511.     }
  2512.     WinSetWindowPos ( hwndFrame, 0, 0, 0, 0, 0, SWP_RESTORE ) ;
  2513.     fHadToRestore = TRUE ;
  2514.   }
  2515.  
  2516.  /***************************************************************************
  2517.   * Determine how many items are to be displayed.                           *
  2518.   ***************************************************************************/
  2519.  
  2520.   HPS hPS = WinGetPS ( hwnd ) ;
  2521.  
  2522.   int Count = 0 ;
  2523.   LONG Widest = 0 ;
  2524.   LONG Height = 0 ;
  2525.  
  2526.   for ( int i=0; i<IniData->ItemCount; i++ )
  2527.   {
  2528.     Item *pItem = IniData->Items [i] ;
  2529.  
  2530.     if ( pItem->QueryFlag() )
  2531.     {
  2532.       Count ++ ;
  2533.  
  2534.       RECTL Rectangle ;
  2535.       pItem->Measure ( hPS, Rectangle ) ;
  2536.  
  2537.       Widest = max ( Widest, (Rectangle.xRight-Rectangle.xLeft+1) ) ;
  2538.  
  2539.       Height += Rectangle.yTop - Rectangle.yBottom ;
  2540.     }
  2541.   }
  2542.  
  2543.   WinReleasePS ( hPS ) ;
  2544.  
  2545.  /***************************************************************************
  2546.   * Get the window's current size & position.                               *
  2547.   ***************************************************************************/
  2548.  
  2549.   RECTL Rectangle ;
  2550.   WinQueryWindowRect ( hwndFrame, &Rectangle ) ;
  2551.  
  2552.   WinCalcFrameRect ( hwndFrame, &Rectangle, TRUE ) ;
  2553.  
  2554.  /***************************************************************************
  2555.   * Adjust the window's width & height.                                     *
  2556.   ***************************************************************************/
  2557.  
  2558.   Rectangle.xRight  = Rectangle.xLeft + Widest ;
  2559.  
  2560.   Rectangle.yTop    = Rectangle.yBottom + Height ;
  2561.  
  2562.  /***************************************************************************
  2563.   * Compute new frame size and apply it.                                    *
  2564.   ***************************************************************************/
  2565.  
  2566.   WinCalcFrameRect ( hwndFrame, &Rectangle, FALSE ) ;
  2567.  
  2568.   WinSetWindowPos ( hwndFrame, 0, 0, 0,
  2569.     (SHORT) (Rectangle.xRight-Rectangle.xLeft),
  2570.     (SHORT) (Rectangle.yTop-Rectangle.yBottom),
  2571.     SWP_SIZE ) ;
  2572.  
  2573.  /***************************************************************************
  2574.   * Return the window to its original state.                                *
  2575.   ***************************************************************************/
  2576.  
  2577.   if ( fHadToRestore )
  2578.   {
  2579.     WinSetWindowPos ( hwndFrame, 0,
  2580.       IniData->Position.x, IniData->Position.y,
  2581.       IniData->Position.cx, IniData->Position.cy,
  2582.       SWP_MOVE | SWP_SIZE | SWP_MINIMIZE ) ;
  2583.   }
  2584.  
  2585.   if ( fHadToHide )
  2586.   {
  2587.     WinShowWindow ( hwndFrame, TRUE ) ;
  2588.   }
  2589.  
  2590.  /***************************************************************************
  2591.   * Invalidate the window so that it gets repainted.                        *
  2592.   ***************************************************************************/
  2593.  
  2594.   WinInvalidateRect ( hwnd, PRECTL(NULL), TRUE ) ;
  2595. }
  2596.  
  2597. /****************************************************************************
  2598.  *                                                                          *
  2599.  *                      Hide Window Controls                                *
  2600.  *                                                                          *
  2601.  ****************************************************************************/
  2602.  
  2603. STATIC void HideControls
  2604. (
  2605.   BOOL fHide,
  2606.   HWND hwndFrame,
  2607.   HWND hwndSysMenu,
  2608.   HWND hwndTitleBar,
  2609.   HWND hwndMinMax
  2610. )
  2611. {
  2612.  /***************************************************************************
  2613.   * Get original window position and state.                                 *
  2614.   ***************************************************************************/
  2615.  
  2616.   SWP OldPosition ;
  2617.   WinQueryWindowPos ( hwndFrame, &OldPosition ) ;
  2618.  
  2619.   BOOL WasVisible = WinIsWindowVisible ( hwndFrame ) ;
  2620.  
  2621.  /***************************************************************************
  2622.   * Restore and hide the window.                                            *
  2623.   ***************************************************************************/
  2624.  
  2625.   WinSetWindowPos ( hwndFrame, 0, 0, 0, 0, 0, SWP_RESTORE | SWP_HIDE ) ;
  2626.  
  2627.  /***************************************************************************
  2628.   * Determine client window and location.                                   *
  2629.   ***************************************************************************/
  2630.  
  2631.   SWP Position ;
  2632.   WinQueryWindowPos ( hwndFrame, &Position ) ;
  2633.  
  2634.   RECTL Rectangle ;
  2635.   Rectangle.xLeft   = Position.x ;
  2636.   Rectangle.xRight  = Position.x + Position.cx ;
  2637.   Rectangle.yBottom = Position.y ;
  2638.   Rectangle.yTop    = Position.y + Position.cy ;
  2639.  
  2640.   WinCalcFrameRect ( hwndFrame, &Rectangle, TRUE ) ;
  2641.  
  2642.  /***************************************************************************
  2643.   * Hide or reveal the controls windows by changing their parentage.        *
  2644.   ***************************************************************************/
  2645.  
  2646.   if ( fHide )
  2647.   {
  2648.     WinSetParent ( hwndSysMenu,  HWND_OBJECT, FALSE ) ;
  2649.     WinSetParent ( hwndTitleBar, HWND_OBJECT, FALSE ) ;
  2650.     WinSetParent ( hwndMinMax,   HWND_OBJECT, FALSE ) ;
  2651.   }
  2652.   else
  2653.   {
  2654.     WinSetParent ( hwndSysMenu,  hwndFrame, TRUE ) ;
  2655.     WinSetParent ( hwndTitleBar, hwndFrame, TRUE ) ;
  2656.     WinSetParent ( hwndMinMax,   hwndFrame, TRUE ) ;
  2657.   }
  2658.  
  2659.  /***************************************************************************
  2660.   * Tell the frame that things have changed.  Let it update the window.     *
  2661.   ***************************************************************************/
  2662.  
  2663.   WinSendMsg ( hwndFrame, WM_UPDATEFRAME,
  2664.     MPFROMSHORT ( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON ), 0L ) ;
  2665.  
  2666.  /***************************************************************************
  2667.   * Reposition the frame around the client window, which is left be.        *
  2668.   ***************************************************************************/
  2669.  
  2670.   WinCalcFrameRect ( hwndFrame, &Rectangle, FALSE ) ;
  2671.  
  2672.   WinSetWindowPos ( hwndFrame, 0,
  2673.     (SHORT) Rectangle.xLeft,  (SHORT) Rectangle.yBottom,
  2674.     (SHORT) (Rectangle.xRight-Rectangle.xLeft),
  2675.     (SHORT) (Rectangle.yTop-Rectangle.yBottom),
  2676.     SWP_SIZE | SWP_MOVE ) ;
  2677.  
  2678.  /***************************************************************************
  2679.   * If window was maximized, put it back that way.                          *
  2680.   ***************************************************************************/
  2681.  
  2682.   if ( OldPosition.fl & SWP_MAXIMIZE )
  2683.   {
  2684.     WinSetWindowPos ( hwndFrame, 0,
  2685.       (SHORT) Rectangle.xLeft,  (SHORT) Rectangle.yBottom,
  2686.       (SHORT) (Rectangle.xRight-Rectangle.xLeft),
  2687.       (SHORT) (Rectangle.yTop-Rectangle.yBottom),
  2688.       SWP_SIZE | SWP_MOVE |
  2689.       ( OldPosition.fl & SWP_MAXIMIZE ) ) ;
  2690.   }
  2691.  
  2692.  /***************************************************************************
  2693.   * If the window was visible in the first place, show it.                  *
  2694.   ***************************************************************************/
  2695.  
  2696.   if ( WasVisible ) {
  2697.     WinShowWindow ( hwndFrame, TRUE ) ;
  2698.   }
  2699. }
  2700.  
  2701. /****************************************************************************
  2702.  *                                                                          *
  2703.  *    Update Window                                                         *
  2704.  *                                                                          *
  2705.  ****************************************************************************/
  2706.  
  2707. STATIC void UpdateWindow ( HWND hwnd, PDATA Data, BOOL All ) {
  2708.  
  2709.  /***************************************************************************
  2710.   * Determine how many items are to be displayed.                           *
  2711.   ***************************************************************************/
  2712.  
  2713.   int Count = 0 ;
  2714.   for ( int i=0; i<Data->IniData.ItemCount; i++ ) {
  2715.     if ( Data->IniData.Items[i]->QueryFlag() ) {
  2716.       Count ++ ;
  2717.     }
  2718.   }
  2719.  
  2720.  /***************************************************************************
  2721.   * Get presentation space and make it use RGB colors.                      *
  2722.   ***************************************************************************/
  2723.  
  2724.   HPS hPS = WinGetPS ( hwnd ) ;
  2725.   GpiCreateLogColorTable ( hPS, LCOL_RESET, LCOLF_RGB, 0L, 0L, PLONG(NULL) ) ;
  2726.  
  2727.  /***************************************************************************
  2728.   * Get the window's size and determine the initial position.               *
  2729.   ***************************************************************************/
  2730.  
  2731.   RECTL Rectangle ;
  2732.   WinQueryWindowRect ( hwnd, &Rectangle ) ;
  2733.  
  2734.   Rectangle.xLeft += Data->Width / 2 ;
  2735.   Rectangle.xRight -= Data->Width / 2 ;
  2736.  
  2737.   Rectangle.yBottom = Data->Height * ( Count - 1 ) ;
  2738.   Rectangle.yTop = Rectangle.yBottom + Data->Height ;
  2739.  
  2740.  /***************************************************************************
  2741.   * Review all items.  Display those changed, or all.                       *
  2742.   ***************************************************************************/
  2743.  
  2744.   for ( i=0; i<Data->IniData.ItemCount; i++ ) {
  2745.     Item *pItem = Data->IniData.Items [i] ;
  2746.     if ( pItem->QueryFlag() ) {
  2747.       pItem->Repaint ( hPS, Rectangle, Data->IniData.TextColor, Data->IniData.BackColor, All ) ;
  2748.       Rectangle.yBottom -= Data->Height ;
  2749.       Rectangle.yTop    -= Data->Height ;
  2750.     }
  2751.   }
  2752.  
  2753.  /***************************************************************************
  2754.   * Release the presentation space and return.                              *
  2755.   ***************************************************************************/
  2756.  
  2757.   WinReleasePS ( hPS ) ;
  2758. }
  2759.  
  2760.  
  2761. /****************************************************************************
  2762.  *                                                                          *
  2763.  *    Monitor Loop Thread                                                   *
  2764.  *                                                                          *
  2765.  ****************************************************************************/
  2766.  
  2767. STATIC VOID _Optlink MonitorLoopThread ( PVOID Parameter ) {
  2768.  
  2769.  /***************************************************************************
  2770.   * Get the thread parameter.                                               *
  2771.   ***************************************************************************/
  2772.  
  2773.   PMONITOR_PARMS Parms = PMONITOR_PARMS ( Parameter ) ;
  2774.  
  2775.  /***************************************************************************
  2776.   * Set this thread's priority.                                             *
  2777.   ***************************************************************************/
  2778.  
  2779.   DosSetPriority ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 ) ;
  2780.   DosSetPriority ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MINIMUM+(*Parms->Priority), 0 ) ;
  2781.  
  2782.  /***************************************************************************
  2783.   * Start up the high resolution timer, if it is available.                 *
  2784.   ***************************************************************************/
  2785.  
  2786.   BOOL HiResTimer = OpenTimer ( ) ;
  2787.  
  2788.  /***************************************************************************
  2789.   * Loop while active . . .                                                 *
  2790.   ***************************************************************************/
  2791.  
  2792.   while ( Parms->Active ) {
  2793.  
  2794.    /*************************************************************************
  2795.     * Reset the last time and count seen.                                   *
  2796.     *************************************************************************/
  2797.  
  2798.     ULONG LastMilliseconds ;
  2799.     TIMESTAMP Time [2] ;
  2800.  
  2801.     if ( HiResTimer )
  2802.       GetTime ( &Time[0] ) ;
  2803.     else
  2804.       DosQuerySysInfo ( QSV_MS_COUNT, QSV_MS_COUNT, &LastMilliseconds, sizeof(LastMilliseconds) ) ;
  2805.  
  2806.     ULONG LastCounter = *Parms->Counter ;
  2807.  
  2808.    /*************************************************************************
  2809.     * Adjust priority and sleep a bit.                                      *
  2810.     *************************************************************************/
  2811.  
  2812. //  DosSetPriority ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 ) ;
  2813. //  DosSetPriority ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MINIMUM+(*Parms->Priority), 0 ) ;
  2814.     DosSleep ( *Parms->Interval ) ;
  2815.  
  2816.    /*************************************************************************
  2817.     * Find out how much time and counts went by.                            *
  2818.     *************************************************************************/
  2819.  
  2820.     ULONG CurrentCounter = *Parms->Counter ;
  2821.  
  2822.     ULONG DeltaMilliseconds ;
  2823.  
  2824.     if ( HiResTimer ) {
  2825.       GetTime ( &Time[1] ) ;
  2826.  
  2827.       ULONG Nanoseconds ;
  2828.       DeltaMilliseconds = ComputeElapsedTime ( &Time[0], &Time[1], &Nanoseconds ) ;
  2829.  
  2830.       if ( Nanoseconds >= 500000L )
  2831.         DeltaMilliseconds ++ ;
  2832.     } else {
  2833.       ULONG Milliseconds ;
  2834.       DosQuerySysInfo ( QSV_MS_COUNT, QSV_MS_COUNT, &Milliseconds, sizeof(Milliseconds) ) ;
  2835.       DeltaMilliseconds = Milliseconds - LastMilliseconds ;
  2836.     }
  2837.  
  2838.    /*************************************************************************
  2839.     * Find out how much idle time was counted.  Adjust it to persecond.     *
  2840.     *************************************************************************/
  2841.  
  2842.     ULONG Counter = (ULONG) ( ( (double)(CurrentCounter-LastCounter) * 1000L ) / (double)DeltaMilliseconds ) ;
  2843.  
  2844.    /*************************************************************************
  2845.     * Tell the owner window to refresh its statistics.                      *
  2846.     *************************************************************************/
  2847.  
  2848.     WinPostMsg ( Parms->Owner, WM_REFRESH, MPFROMLONG(Counter), 0L ) ;
  2849.   }
  2850. }
  2851.  
  2852. /****************************************************************************
  2853.  *                                                                          *
  2854.  *      Update the Item List to reflect changes in the available drives.    *
  2855.  *                                                                          *
  2856.  ****************************************************************************/
  2857.  
  2858. STATIC VOID UpdateDriveList
  2859. (
  2860.   HAB Anchor,
  2861.   HMODULE Library,
  2862.   HINI IniHandle,
  2863.   PINIDATA IniData,
  2864.   ULONG OldDrives,
  2865.   ULONG NewDrives
  2866. )
  2867. {
  2868.  /***************************************************************************
  2869.   * Get format strings.                                                     *
  2870.   ***************************************************************************/
  2871.  
  2872.   ResourceString LabelFormat ( Library, IDS_SHOW_DRIVE_FREE_LABEL ) ;
  2873.   ResourceString OptionFormat ( Library, IDS_SHOW_DRIVE_FREE_OPTION ) ;
  2874.  
  2875.  /***************************************************************************
  2876.   * Save the old item list for comparison.                                  *
  2877.   ***************************************************************************/
  2878.  
  2879.   Item *OldItems [ ITEM_BASE_COUNT + MAX_DRIVES ] ;
  2880.  
  2881.   memset ( OldItems, 0, sizeof(OldItems) ) ;
  2882.  
  2883.   USHORT OldCount = 0 ;
  2884.   if ( OldDrives )
  2885.   {
  2886.     OldCount = IniData->ItemCount ;
  2887.     memcpy ( OldItems, IniData->Items, sizeof(OldItems) ) ;
  2888.   }
  2889.  
  2890.  /***************************************************************************
  2891.   * Add items for each drive on the system.                                 *
  2892.   ***************************************************************************/
  2893.  
  2894.   USHORT Count = ITEM_BASE_COUNT ;
  2895.   USHORT OldIndex = ITEM_BASE_COUNT ;
  2896.  
  2897.   ULONG Drives = 0 ;
  2898.   NewDrives >>= 2 ;
  2899.   OldDrives >>= 2 ;
  2900.  
  2901.   for ( int Drive=3; Drive<=MAX_DRIVES; Drive++ )
  2902.   {
  2903.     while ( ( OldIndex < OldCount )
  2904.       AND ( (SHORT)OldItems[OldIndex]->QueryId() < ITEM_BASE_COUNT + Drive ) )
  2905.     {
  2906.       OldIndex ++ ;
  2907.     }
  2908.  
  2909.     if ( NewDrives & 1 )
  2910.     {
  2911.       if ( OldDrives & 1 )
  2912.       {
  2913.         Drives |= ( 1 << (Drive-1) ) ;
  2914.         if ( ( OldIndex < OldCount )
  2915.           AND ( (SHORT)OldItems[OldIndex]->QueryId() == ITEM_BASE_COUNT + Drive ) )
  2916.         {
  2917.           IniData->Items[Count++] = OldItems[OldIndex++] ;
  2918.         }
  2919.       }
  2920.       else
  2921.       {
  2922.         BYTE FileSystem [80] ;
  2923.         BYTE DiskLabel [12] ;
  2924.         int DriveType = CheckDrive ( Drive, FileSystem, DiskLabel ) ;
  2925.         if ( DriveType ) {
  2926.  
  2927.           if ( DriveType > 0 )
  2928.             Drives |= ( 1 << (Drive-1) ) ;
  2929.  
  2930.           BYTE Name [80] ;
  2931.           sprintf ( PCHAR(Name),   "ShowDrive%c:", Drive+'A'-1 ) ;
  2932.  
  2933.           BYTE Label [80] ;
  2934.           sprintf ( PCHAR(Label),  PCHAR(LabelFormat),  Drive+'A'-1 ) ;
  2935.  
  2936.           BYTE Option [80] ;
  2937.           sprintf ( PCHAR(Option), PCHAR(OptionFormat), Drive+'A'-1 ) ;
  2938.  
  2939.           IniData->Items[Count++] = new DriveFree ( ITEM_BASE_COUNT+Drive,
  2940.             Name, Label, Option, IniData->CountryInfo,
  2941.             Drive, IniData->DriveError, 
  2942.             IniData->ShowFileSystemNames, FileSystem, 
  2943.             IniData->ShowDiskLabels, DiskLabel ) ;
  2944.         }
  2945.       }
  2946.     }
  2947.     else
  2948.     {
  2949.       if ( OldDrives & 1 )
  2950.       {
  2951.         delete OldItems[OldIndex++] ;
  2952.       }
  2953.       else
  2954.       {
  2955.         // Do nothing.
  2956.       }
  2957.     }
  2958.  
  2959.     NewDrives >>= 1 ;
  2960.     OldDrives >>= 1 ;
  2961.   }
  2962.  
  2963.  /***************************************************************************
  2964.   * Save the new item count.                                                *
  2965.   ***************************************************************************/
  2966.  
  2967.   IniData->ItemCount = Count ;
  2968.  
  2969.  /***************************************************************************
  2970.   * Fetch the display flags for the drives.                                 *
  2971.   ***************************************************************************/
  2972.  
  2973.   for ( int i=ITEM_BASE_COUNT; i<IniData->ItemCount; i++ )
  2974.   {
  2975.     BOOL Flag = TRUE ;
  2976.     Item *pItem = IniData->Items [i] ;
  2977.     ULONG Size ;
  2978.  
  2979.     if
  2980.     (
  2981.       PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), pItem->QueryName(), &Size )
  2982.       AND
  2983.       ( ( Size == sizeof(Flag) ) OR ( Size == sizeof(short) ) )
  2984.       AND
  2985.       PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), pItem->QueryName(), &Flag, &Size )
  2986.     )
  2987.     {
  2988.       ;
  2989.     }
  2990.  
  2991.     if ( Flag )
  2992.       pItem->SetFlag () ;
  2993.     else
  2994.       pItem->ResetFlag () ;
  2995.   }
  2996.  
  2997.  /***************************************************************************
  2998.   * Update the total free space object.                                     *
  2999.   ***************************************************************************/
  3000.  
  3001.   ( (TotalFree*) IniData->Items [ ITEM_TOTALFREE ] ) -> ResetMask ( Drives ) ;
  3002. }
  3003.  
  3004. /****************************************************************************
  3005.  *                                                                          *
  3006.  *      Check to see if drive should be added to display list.              *
  3007.  *                                                                          *
  3008.  ****************************************************************************/
  3009.  
  3010. STATIC int CheckDrive ( USHORT Drive, PBYTE FileSystem, PBYTE DiskLabel ) {
  3011.  
  3012.  /***************************************************************************
  3013.   * First, check to see if drive is local or remote.  Remote drives are     *
  3014.   *   always monitored.                                                     *
  3015.   ***************************************************************************/
  3016.  
  3017.   BYTE Path [3] ;
  3018.   Path[0] = (BYTE) ( Drive + 'A' - 1 ) ;
  3019.   Path[1] = ':' ;
  3020.   Path[2] = 0 ;
  3021.  
  3022.   DosError ( FERR_DISABLEHARDERR ) ;
  3023.  
  3024.   BYTE Buffer [1024] ;
  3025.   ULONG Size = sizeof(Buffer) ;
  3026.   ULONG Status = DosQueryFSAttach ( Path, 0, FSAIL_QUERYNAME, (PFSQBUFFER2)Buffer, &Size ) ;
  3027.   DosError ( FERR_ENABLEHARDERR ) ;
  3028.  
  3029.   if ( Status ) {
  3030. //  Log ( "ERROR: Unable to query drive %s for file system.  Status %04X.",
  3031. //    Path, Status ) ;
  3032.     return ( 0 ) ;   // Don't monitor.
  3033.   }
  3034.  
  3035.   USHORT cbName = PFSQBUFFER2(Buffer)->cbName ;
  3036.   strcpy ( PCHAR(FileSystem), PCHAR(PFSQBUFFER2(Buffer+cbName)->szFSDName) ) ;
  3037.  
  3038.   if ( PFSQBUFFER2(Buffer)->iType == FSAT_REMOTEDRV ) {
  3039.     return ( -1 ) ;  // Monitor but don't include in the total over all drives.
  3040.   }
  3041.  
  3042.  /***************************************************************************
  3043.   * Attempt to open the local drive as an entire device.  If unable to do   *
  3044.   *   so, we cannot monitor this drive.                                     *
  3045.   ***************************************************************************/
  3046.  
  3047.   ULONG Action ;
  3048.   HFILE Handle ;
  3049.   Status = DosOpen ( Path, &Handle, &Action, 0, 0, FILE_OPEN,
  3050.     OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE |
  3051.     OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, 0 ) ;
  3052.  
  3053.   if ( Status ) {
  3054. //  Log ( "ERROR: Unable to open local drive %s.  Status %04X.",
  3055. //    Path, Status ) ;
  3056.     return ( 0 ) ;   // Don't monitor.
  3057.   }
  3058.  
  3059.  /***************************************************************************
  3060.   * Check to see if the drive has removable media.  We cannot monitor such. *
  3061.   ***************************************************************************/
  3062.  
  3063.   BOOL Addit = FALSE ;
  3064.   BYTE Command = 0 ;
  3065.   BYTE NonRemovable ;
  3066.  
  3067.   ULONG LengthIn = sizeof(Command) ;
  3068.   ULONG LengthOut = sizeof(NonRemovable);
  3069.  
  3070.   if ( 
  3071.     NOT DosDevIOCtl 
  3072.     ( 
  3073.       Handle, 8, 0x20, 
  3074.       &Command, sizeof(Command), &LengthIn,
  3075.       &NonRemovable, sizeof(NonRemovable), &LengthOut 
  3076.     ) 
  3077.   ) {
  3078.     Addit = NonRemovable ;
  3079.   }
  3080.  
  3081.  /***************************************************************************
  3082.   * Close the drive.                                                        *
  3083.   ***************************************************************************/
  3084.  
  3085.   DosClose ( Handle ) ;
  3086.  
  3087.  /***************************************************************************
  3088.   * Get the drive label.                                                    *
  3089.   ***************************************************************************/
  3090.  
  3091.   FSINFO Info ;
  3092.   DosQueryFSInfo ( Drive, FSIL_VOLSER, PBYTE(&Info), sizeof(Info) ) ;
  3093.   strcpy ( PCHAR(DiskLabel), PCHAR(Info.vol.szVolLabel) ) ;
  3094.  
  3095.  /***************************************************************************
  3096.   * Return the final verdict.                                               *
  3097.   ***************************************************************************/
  3098.  
  3099.   return ( Addit ) ;    // Monitor and include in overall total if not removable.
  3100. }
  3101.  
  3102. /****************************************************************************
  3103.  *                                                                          *
  3104.  *                       Calibrate the Load Meter                           *
  3105.  *                                                                          *
  3106.  ****************************************************************************/
  3107.  
  3108. STATIC ULONG CalibrateLoadMeter ( PCOUNTER_PARMS Parms ) {
  3109.  
  3110.  /***************************************************************************
  3111.   * Set result to zero as a default.                                        *
  3112.   ***************************************************************************/
  3113.  
  3114.   double AdjustedMaxLoad = 0.0 ;
  3115.  
  3116.  /***************************************************************************
  3117.   * If HRTIMER.SYS has been installed . . .                                 *
  3118.   ***************************************************************************/
  3119.  
  3120.   if ( OpenTimer ( ) ) {
  3121.  
  3122.    /*************************************************************************
  3123.     * Increase this thread's priority to the maximum.                       *
  3124.     *************************************************************************/
  3125.  
  3126.     DosSetPriority ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 ) ;
  3127.  
  3128.    /*************************************************************************
  3129.     * Create the calibration thread and set its priority next highest.      *
  3130.     *************************************************************************/
  3131.  
  3132.     Parms->Active = TRUE ;
  3133.     TID tidCalibrate = _beginthread ( CounterThread, NULL, 0x3000, Parms ) ;
  3134.     DosSuspendThread ( tidCalibrate ) ;
  3135.     DosSetPriority ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, tidCalibrate ) ;
  3136.     DosSetPriority ( PRTYS_THREAD, PRTYC_TIMECRITICAL, -1, tidCalibrate ) ;
  3137.  
  3138.    /*************************************************************************
  3139.     * Reset the calibration count, get the time, and let the counter go.    *
  3140.     *************************************************************************/
  3141.  
  3142.     Parms->Counter = 0 ;
  3143.     TIMESTAMP Time[2] ;
  3144.     GetTime ( &Time[0] ) ;
  3145.     DosResumeThread ( tidCalibrate ) ;
  3146.  
  3147.    /*************************************************************************
  3148.     * Sleep for one second.                                                 *
  3149.     *************************************************************************/
  3150.  
  3151.     DosSleep ( 1000 ) ;
  3152.  
  3153.    /*************************************************************************
  3154.     * Suspend the calibration counter and get the time.                     *
  3155.     *************************************************************************/
  3156.  
  3157.     Parms->Active = FALSE ;
  3158.     DosWaitThread ( &tidCalibrate, DCWW_WAIT ) ;
  3159.     GetTime ( &Time[1] ) ;
  3160.  
  3161.    /*************************************************************************
  3162.     * Return priorities to normal.                                          *
  3163.     *************************************************************************/
  3164.  
  3165.     DosSetPriority ( PRTYS_THREAD, PRTYC_REGULAR, 0, 0 ) ;
  3166.  
  3167.    /*************************************************************************
  3168.     * Get the elapsed time and adjust the calibration count.                *
  3169.     *************************************************************************/
  3170.  
  3171.     ULONG Milliseconds ;
  3172.     ULONG Nanoseconds ;
  3173.     Milliseconds = ComputeElapsedTime ( &Time[0], &Time[1], &Nanoseconds ) ;
  3174.  
  3175.     AdjustedMaxLoad = (double)Parms->Counter * 1.0E9 ;
  3176.     AdjustedMaxLoad /= (double)Milliseconds*1.0E6L + (double)Nanoseconds ;
  3177.  
  3178.    /*************************************************************************
  3179.     * Close down the connection to HRTIMER.SYS.                             *
  3180.     *************************************************************************/
  3181.  
  3182.     CloseTimer ( ) ;
  3183.   }
  3184.  
  3185.  /***************************************************************************
  3186.   * Return the adjusted calibration count.  If HRTIMER was not there, it    *
  3187.   *   will be zero.                                                         *
  3188.   ***************************************************************************/
  3189.  
  3190.   return ( (ULONG)AdjustedMaxLoad ) ;
  3191. }
  3192.  
  3193. /****************************************************************************
  3194.  *                                                                          *
  3195.  *                    General Purpose Counter Thread                        *
  3196.  *                                                                          *
  3197.  ****************************************************************************/
  3198.  
  3199. STATIC VOID _Optlink CounterThread ( PVOID Parameter ) {
  3200.    PCOUNTER_PARMS Parms = PCOUNTER_PARMS ( Parameter ) ;
  3201.    while ( Parms->Active ) {
  3202.       Parms->Counter ++ ;
  3203.    }
  3204. }
  3205.